From e8881a28d6697a668d4d1f1ef5f4556e548caa2e Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 10:15:38 +0100 Subject: [PATCH 01/47] Wrap service with a div --- classes/service.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/classes/service.php b/classes/service.php index 268715c..f771b4a 100644 --- a/classes/service.php +++ b/classes/service.php @@ -244,18 +244,20 @@ class Service implements JsonSerializable } // Render the service status + echo '
'; echo '
  • ' . $this->name .''; //echo '
  • ' . $this->name . ''; if(!empty($this->description)) { echo ' '; } - if ($this->status!=-1){?>
    status]);?>
    + if ($this->status!=-1){?>
    status]);?>
    '; if ( isset($boolFinish) && $boolFinish) { echo ''; } + echo '
  • '; } public function jsonSerialize() { From d5a4beae84161043e380086a556794fc590e2ac7 Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 10:29:57 +0100 Subject: [PATCH 02/47] fix variables forgotten $ and wrong variable --- template.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/template.php b/template.php index ba89407..51e351d 100644 --- a/template.php +++ b/template.php @@ -56,9 +56,9 @@ class Template{ Date: Thu, 18 Mar 2021 11:42:26 +0100 Subject: [PATCH 03/47] fix head.txt path #142 --- template.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/template.php b/template.php index 51e351d..e0e058e 100644 --- a/template.php +++ b/template.php @@ -57,8 +57,9 @@ class Template{ Date: Thu, 18 Mar 2021 11:54:42 +0100 Subject: [PATCH 04/47] fix variables #142 --- template.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/template.php b/template.php index e0e058e..d8dc300 100644 --- a/template.php +++ b/template.php @@ -26,7 +26,7 @@ class Template{ if ( 'admin' == $str_url ) { $strSubsMenu = ''; } else { - if (SUBSCRIBE_EMAIL || SUBSCRIBE_TELEGRAM ) { + if ($SUBSCRIBE_EMAIL || $SUBSCRIBE_TELEGRAM ) { // Subscriber menu is to be shown... $strSubsMenu = ' -
    +
    @@ -236,7 +214,7 @@ class Template{ - + From e5907f91bbefcbf22d320634b66e7d3b8ffd4686 Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 18:01:32 +0100 Subject: [PATCH 08/47] transparent input fields for new incidents --- css/main.css | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/css/main.css b/css/main.css index 79c956d..2909dfe 100644 --- a/css/main.css +++ b/css/main.css @@ -182,7 +182,13 @@ a:focus { opacity: 1; } -.card-body textarea { +article.card input { +background: transparent; +border: none; +border-bottom: 1px white outset; +} + +article.card textarea { width: 100%; background: transparent; border: none; From e2e4a9620b95b45e4eaa0e82da5f63cf92aadfad Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 18:23:06 +0100 Subject: [PATCH 09/47] jquerry deleted by mistake --- js/vendor/jquery-3.5.1.min.js | 2 + js/vendor/jquery.growl.js | 311 ++++++++++++++++++++++++++++++++++ js/vendor/jquery.timeago.js | 232 +++++++++++++++++++++++++ 3 files changed, 545 insertions(+) create mode 100644 js/vendor/jquery-3.5.1.min.js create mode 100644 js/vendor/jquery.growl.js create mode 100644 js/vendor/jquery.timeago.js diff --git a/js/vendor/jquery-3.5.1.min.js b/js/vendor/jquery-3.5.1.min.js new file mode 100644 index 0000000..b061403 --- /dev/null +++ b/js/vendor/jquery-3.5.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 0 && arguments[0] !== undefined ? arguments[0] : {}; + + return new Growl(settings); + } + }]); + + function Growl() { + var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, Growl); + + this.render = this.render.bind(this); + this.bind = this.bind.bind(this); + this.unbind = this.unbind.bind(this); + this.mouseEnter = this.mouseEnter.bind(this); + this.mouseLeave = this.mouseLeave.bind(this); + this.click = this.click.bind(this); + this.close = this.close.bind(this); + this.cycle = this.cycle.bind(this); + this.waitAndDismiss = this.waitAndDismiss.bind(this); + this.present = this.present.bind(this); + this.dismiss = this.dismiss.bind(this); + this.remove = this.remove.bind(this); + this.animate = this.animate.bind(this); + this.$growls = this.$growls.bind(this); + this.$growl = this.$growl.bind(this); + this.html = this.html.bind(this); + this.content = this.content.bind(this); + this.container = this.container.bind(this); + this.settings = $.extend({}, Growl.settings, settings); + this.initialize(this.settings.location); + this.render(); + } + + _createClass(Growl, [{ + key: "initialize", + value: function initialize(location) { + var id; + id = 'growls-' + location; + return $('body:not(:has(#' + id + '))').append('
    '); + } + }, { + key: "render", + value: function render() { + var $growl; + $growl = this.$growl(); + this.$growls(this.settings.location).append($growl); + if (this.settings.fixed) { + this.present(); + } else { + this.cycle(); + } + } + }, { + key: "bind", + value: function bind() { + var $growl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.$growl(); + + $growl.on("click", this.click); + if (this.settings.delayOnHover) { + $growl.on("mouseenter", this.mouseEnter); + $growl.on("mouseleave", this.mouseLeave); + } + return $growl.on("contextmenu", this.close).find("." + this.settings.namespace + "-close").on("click", this.close); + } + }, { + key: "unbind", + value: function unbind() { + var $growl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.$growl(); + + $growl.off("click", this.click); + if (this.settings.delayOnHover) { + $growl.off("mouseenter", this.mouseEnter); + $growl.off("mouseleave", this.mouseLeave); + } + return $growl.off("contextmenu", this.close).find("." + this.settings.namespace + "-close").off("click", this.close); + } + }, { + key: "mouseEnter", + value: function mouseEnter(event) { + var $growl; + $growl = this.$growl(); + return $growl.stop(true, true); + } + }, { + key: "mouseLeave", + value: function mouseLeave(event) { + return this.waitAndDismiss(); + } + }, { + key: "click", + value: function click(event) { + if (this.settings.url != null) { + event.preventDefault(); + event.stopPropagation(); + return window.open(this.settings.url); + } + } + }, { + key: "close", + value: function close(event) { + var $growl; + event.preventDefault(); + event.stopPropagation(); + $growl = this.$growl(); + return $growl.stop().queue(this.dismiss).queue(this.remove); + } + }, { + key: "cycle", + value: function cycle() { + var $growl; + $growl = this.$growl(); + return $growl.queue(this.present).queue(this.waitAndDismiss()); + } + }, { + key: "waitAndDismiss", + value: function waitAndDismiss() { + var $growl; + $growl = this.$growl(); + return $growl.delay(this.settings.duration).queue(this.dismiss).queue(this.remove); + } + }, { + key: "present", + value: function present(callback) { + var $growl; + $growl = this.$growl(); + this.bind($growl); + return this.animate($growl, this.settings.namespace + "-incoming", 'out', callback); + } + }, { + key: "dismiss", + value: function dismiss(callback) { + var $growl; + $growl = this.$growl(); + this.unbind($growl); + return this.animate($growl, this.settings.namespace + "-outgoing", 'in', callback); + } + }, { + key: "remove", + value: function remove(callback) { + this.$growl().remove(); + return typeof callback === "function" ? callback() : void 0; + } + }, { + key: "animate", + value: function animate($element, name) { + var direction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'in'; + var callback = arguments[3]; + + var transition; + transition = Animation.transition($element); + $element[direction === 'in' ? 'removeClass' : 'addClass'](name); + $element.offset().position; + $element[direction === 'in' ? 'addClass' : 'removeClass'](name); + if (callback == null) { + return; + } + if (transition != null) { + $element.one(transition, callback); + } else { + callback(); + } + } + }, { + key: "$growls", + value: function $growls(location) { + var base; + if (this.$_growls == null) { + this.$_growls = []; + } + return (base = this.$_growls)[location] != null ? base[location] : base[location] = $('#growls-' + location); + } + }, { + key: "$growl", + value: function $growl() { + return this.$_growl != null ? this.$_growl : this.$_growl = $(this.html()); + } + }, { + key: "html", + value: function html() { + return this.container(this.content()); + } + }, { + key: "content", + value: function content() { + return "
    " + this.settings.close + "
    \n
    " + this.settings.title + "
    \n
    " + this.settings.message + "
    "; + } + }, { + key: "container", + value: function container(content) { + return "
    \n " + content + "\n
    "; + } + }]); + + return Growl; + }(); + + ; + + Growl.settings = { + namespace: 'growl', + duration: 3200, + close: "×", + location: "default", + style: "default", + size: "medium", + delayOnHover: true + }; + + return Growl; + }(); + + this.Growl = Growl; + + $.growl = function () { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + return Growl.growl(options); + }; + + $.growl.error = function () { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var settings; + settings = { + title: "Error!", + style: "error" + }; + return $.growl($.extend(settings, options)); + }; + + $.growl.notice = function () { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var settings; + settings = { + title: "Notice!", + style: "notice" + }; + return $.growl($.extend(settings, options)); + }; + + $.growl.warning = function () { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var settings; + settings = { + title: "Warning!", + style: "warning" + }; + return $.growl($.extend(settings, options)); + }; +}).call(this); \ No newline at end of file diff --git a/js/vendor/jquery.timeago.js b/js/vendor/jquery.timeago.js new file mode 100644 index 0000000..ec80c32 --- /dev/null +++ b/js/vendor/jquery.timeago.js @@ -0,0 +1,232 @@ +/** + * Timeago is a jQuery plugin that makes it easy to support automatically + * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago"). + * + * @name timeago + * @version 1.6.7 + * @requires jQuery >=1.5.0 <4.0 + * @author Ryan McGeary + * @license MIT License - http://www.opensource.org/licenses/mit-license.php + * + * For usage and examples, visit: + * http://timeago.yarp.com/ + * + * Copyright (c) 2008-2019, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org) + */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + factory(require('jquery')); + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + $.timeago = function(timestamp) { + if (timestamp instanceof Date) { + return inWords(timestamp); + } else if (typeof timestamp === "string") { + return inWords($.timeago.parse(timestamp)); + } else if (typeof timestamp === "number") { + return inWords(new Date(timestamp)); + } else { + return inWords($.timeago.datetime(timestamp)); + } + }; + var $t = $.timeago; + + $.extend($.timeago, { + settings: { + refreshMillis: 60000, + allowPast: true, + allowFuture: false, + localeTitle: false, + cutoff: 0, + autoDispose: true, + strings: { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "ago", + suffixFromNow: "from now", + inPast: "any moment now", + seconds: "less than a minute", + minute: "about a minute", + minutes: "%d minutes", + hour: "about an hour", + hours: "about %d hours", + day: "a day", + days: "%d days", + month: "about a month", + months: "%d months", + year: "about a year", + years: "%d years", + wordSeparator: " ", + numbers: [] + } + }, + + inWords: function(distanceMillis) { + if (!this.settings.allowPast && ! this.settings.allowFuture) { + throw 'timeago allowPast and allowFuture settings can not both be set to false.'; + } + + var $l = this.settings.strings; + var prefix = $l.prefixAgo; + var suffix = $l.suffixAgo; + if (this.settings.allowFuture) { + if (distanceMillis < 0) { + prefix = $l.prefixFromNow; + suffix = $l.suffixFromNow; + } + } + + if (!this.settings.allowPast && distanceMillis >= 0) { + return this.settings.strings.inPast; + } + + var seconds = Math.abs(distanceMillis) / 1000; + var minutes = seconds / 60; + var hours = minutes / 60; + var days = hours / 24; + var years = days / 365; + + function substitute(stringOrFunction, number) { + var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; + var value = ($l.numbers && $l.numbers[number]) || number; + return string.replace(/%d/i, value); + } + + var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || + seconds < 90 && substitute($l.minute, 1) || + minutes < 45 && substitute($l.minutes, Math.round(minutes)) || + minutes < 90 && substitute($l.hour, 1) || + hours < 24 && substitute($l.hours, Math.round(hours)) || + hours < 42 && substitute($l.day, 1) || + days < 30 && substitute($l.days, Math.round(days)) || + days < 45 && substitute($l.month, 1) || + days < 365 && substitute($l.months, Math.round(days / 30)) || + years < 1.5 && substitute($l.year, 1) || + substitute($l.years, Math.round(years)); + + var separator = $l.wordSeparator || ""; + if ($l.wordSeparator === undefined) { separator = " "; } + return $.trim([prefix, words, suffix].join(separator)); + }, + + parse: function(iso8601) { + var s = $.trim(iso8601); + s = s.replace(/\.\d+/,""); // remove milliseconds + s = s.replace(/-/,"/").replace(/-/,"/"); + s = s.replace(/T/," ").replace(/Z/," UTC"); + s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 + s = s.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900 + return new Date(s); + }, + datetime: function(elem) { + var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title"); + return $t.parse(iso8601); + }, + isTime: function(elem) { + // jQuery's `is()` doesn't play well with HTML5 in IE + return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); + } + }); + + // functions that can be called via $(el).timeago('action') + // init is default when no action is given + // functions are called with context of a single element + var functions = { + init: function() { + functions.dispose.call(this); + var refresh_el = $.proxy(refresh, this); + refresh_el(); + var $s = $t.settings; + if ($s.refreshMillis > 0) { + this._timeagoInterval = setInterval(refresh_el, $s.refreshMillis); + } + }, + update: function(timestamp) { + var date = (timestamp instanceof Date) ? timestamp : $t.parse(timestamp); + $(this).data('timeago', { datetime: date }); + if ($t.settings.localeTitle) { + $(this).attr("title", date.toLocaleString()); + } + refresh.apply(this); + }, + updateFromDOM: function() { + $(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) }); + refresh.apply(this); + }, + dispose: function () { + if (this._timeagoInterval) { + window.clearInterval(this._timeagoInterval); + this._timeagoInterval = null; + } + } + }; + + $.fn.timeago = function(action, options) { + var fn = action ? functions[action] : functions.init; + if (!fn) { + throw new Error("Unknown function name '"+ action +"' for timeago"); + } + // each over objects here and call the requested function + this.each(function() { + fn.call(this, options); + }); + return this; + }; + + function refresh() { + var $s = $t.settings; + + //check if it's still visible + if ($s.autoDispose && !$.contains(document.documentElement,this)) { + //stop if it has been removed + $(this).timeago("dispose"); + return this; + } + + var data = prepareData(this); + + if (!isNaN(data.datetime)) { + if ( $s.cutoff === 0 || Math.abs(distance(data.datetime)) < $s.cutoff) { + $(this).text(inWords(data.datetime)); + } else { + if ($(this).attr('title').length > 0) { + $(this).text($(this).attr('title')); + } + } + } + return this; + } + + function prepareData(element) { + element = $(element); + if (!element.data("timeago")) { + element.data("timeago", { datetime: $t.datetime(element) }); + var text = $.trim(element.text()); + if ($t.settings.localeTitle) { + element.attr("title", element.data('timeago').datetime.toLocaleString()); + } else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) { + element.attr("title", text); + } + } + return element.data("timeago"); + } + + function inWords(date) { + return $t.inWords(distance(date)); + } + + function distance(date) { + return (new Date().getTime() - date.getTime()); + } + + // fix for IE6 suckage + document.createElement("abbr"); + document.createElement("time"); +})); From bf3048baf8f31697f3138387a6de467aba78b002 Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 18:26:03 +0100 Subject: [PATCH 10/47] files reformatted for better readability --- 404.php | 21 +- admin/dashboard.php | 128 +++++---- admin/index.php | 87 +++--- admin/login-form.php | 54 ++-- admin/lost-password.php | 129 +++++---- admin/new-user.php | 53 ++-- admin/options.php | 237 +++++++++-------- admin/service-group.php | 77 +++--- admin/service.php | 72 +++-- admin/settings.php | 153 +++++------ admin/user.php | 46 ++-- api/incidents.php | 18 +- api/status.php | 36 ++- classes/constellation.php | 115 ++++---- classes/db-class.php | 60 +++-- classes/incident.php | 128 +++++---- classes/locale-negotiator.php | 83 +++--- classes/mailer.php | 60 +++-- classes/notification.php | 27 +- classes/queue.php | 282 ++++++++++---------- classes/service-group.php | 43 ++- classes/service.php | 141 +++++----- classes/subscriber.php | 36 ++- classes/subscriptions.php | 62 ++--- classes/telegram.php | 153 +++++------ classes/token.php | 11 +- classes/user.php | 485 ++++++++++++++++------------------ create-server-config.php | 1 - css/main.css | 6 +- css/print.css | 163 ++++++------ email_subscriptions.php | 123 ++++----- index.php | 147 +++++------ install.php | 275 ++++++++++--------- install.sql | 102 +++---- js/admin.js | 110 ++++---- js/main.js | 55 ++-- policy.php | 58 ++-- subscriptions.php | 21 +- telegram_check.php | 19 +- template.php | 407 ++++++++++++++-------------- 40 files changed, 2079 insertions(+), 2205 deletions(-) diff --git a/404.php b/404.php index 1f01ea7..4da48e2 100644 --- a/404.php +++ b/404.php @@ -1,17 +1,16 @@ -
    -

    -

    +

    +

    -render_incidents(false,$_GET['offset'],5); +if (isset($_GET['ajax'])) { + $constellation->render_incidents(false, $_GET['offset'], 5); exit(); -}else if (isset($_GET['offset'])) -{ +} else if (isset($_GET['offset'])) { $offset = $_GET['offset']; } -if (isset($_GET['new']) && $_GET['new']=="incident") -{ +if (isset($_GET['new']) && $_GET['new'] == "incident") { Incident::add(); } -if (isset($_GET['delete'])) -{ +if (isset($_GET['delete'])) { Incident::delete($_GET['delete']); } if (isset($_GET['tasks'])) { - Queue::process_queue(); + Queue::process_queue(); } Template::render_header(_("Dashboard"), true); ?> -
    -

    -

    get_name();?>

    -
    +
    +

    +

    get_name(); ?>

    +
    -
    - render_status(true); - ?> -
    -
    -
    -
    -
    -

    -
    +
    + render_status(true); + ?> +
    +
    +
    +
    +
    +

    +
    - -

    + +

    - -
    - get_status()!=-1){?> -
    - get_id(), $post_services))?"checked":'';?> id="service-get_id(); ?>"> -
    - - - -
    - + foreach ($services as $service) { + ?> +
    + get_status() != -1) { ?> +
    + get_id(), $post_services)) ? "checked" : ''; ?> id="service-get_id(); ?>"> +
    + + + +
    +
    - " value="" required> + " value="" required> - "> + ">
    -

    +

    @@ -95,26 +91,24 @@ Template::render_header(_("Dashboard"), true);
    - +
    - - render_incidents(true,$offset,5,true); - $constellation->render_incidents(false,$offset,5,true); - ?> -
    + + render_incidents(true, $offset, 5, true); + $constellation->render_incidents(false, $offset, 5, true); + ?>
    +
    \ No newline at end of file diff --git a/admin/index.php b/admin/index.php index 345f89c..2184858 100644 --- a/admin/index.php +++ b/admin/index.php @@ -1,10 +1,8 @@ getSetting($mysqli,"name")); - define("TITLE", $db->getSetting($mysqli,"title")); - define("WEB_URL", $db->getSetting($mysqli,"url")); - define("MAILER_NAME", $db->getSetting($mysqli,"mailer")); - define("MAILER_ADDRESS", $db->getSetting($mysqli,"mailer_email")); + define("NAME", $db->getSetting($mysqli, "name")); + define("TITLE", $db->getSetting($mysqli, "title")); + define("WEB_URL", $db->getSetting($mysqli, "url")); + define("MAILER_NAME", $db->getSetting($mysqli, "mailer")); + define("MAILER_ADDRESS", $db->getSetting($mysqli, "mailer_email")); define("GOOGLE_RECAPTCHA", $db->getBooleanSetting($mysqli, "google_recaptcha")); define("GOOGLE_RECAPTCHA_SECRET", $db->getSetting($mysqli, "google_recaptcha_secret")); @@ -39,58 +37,45 @@ else{ // Process the subscriber notification queue // If CRON_SERVER_IP is not set, call notification once incident has been saved - if ( empty(CRON_SERVER_IP) ) - { - if ( isset($_GET['sent']) && $_GET['sent'] == true ) - { + if (empty(CRON_SERVER_IP)) { + if (isset($_GET['sent']) && $_GET['sent'] == true) { Queue::process_queue(); } - } - else if ( isset($_GET['task']) && $_GET['task'] == 'cron' ) - { + } else if (isset($_GET['task']) && $_GET['task'] == 'cron') { // Else, base it on call to /admin?task=cron being called from IP defined by CRON_SERVER_IP - if (! empty(CRON_SERVER_IP) && $_SERVER['REMOTE_ADDR'] == CRON_SERVER_IP ) - { - Queue::process_queue(); - syslog(1, "CRON server processed"); - } - else { - syslog(1, "CRON called from unauthorised server"); + if (!empty(CRON_SERVER_IP) && $_SERVER['REMOTE_ADDR'] == CRON_SERVER_IP) { + Queue::process_queue(); + syslog(1, "CRON server processed"); + } else { + syslog(1, "CRON called from unauthorised server"); } } - if(isset($_COOKIE['user'])&&!isset($_SESSION['user'])) - { + if (isset($_COOKIE['user']) && !isset($_SESSION['user'])) { User::restore_session(); } - if (!isset($_SESSION['user'])) - { - if (isset($_GET['do']) && $_GET['do']=="lost-password") - { + if (!isset($_SESSION['user'])) { + if (isset($_GET['do']) && $_GET['do'] == "lost-password") { require_once("lost-password.php"); - }else if (isset($_GET['do']) && $_GET['do']=="change-email"){ + } else if (isset($_GET['do']) && $_GET['do'] == "change-email") { $user_pwd = new User($_GET['id']); $user_pwd->change_email(); require_once("login-form.php"); - } - else{ + } else { User::login(); require_once("login-form.php"); } - } - else - { + } else { $user = new User($_SESSION['user']); - if (!$user->is_active()) - { + if (!$user->is_active()) { User::logout(); } - if (!isset($_GET['do'])){ + if (!isset($_GET['do'])) { $do = ""; - }else{ + } else { $do = $_GET['do']; } @@ -98,17 +83,17 @@ else{ case 'change-email': $user = new User($_GET['id']); $user->change_email(); - case 'user': - require_once("user.php"); - break; + case 'user': + require_once("user.php"); + break; - case 'settings': - require_once("settings.php"); - break; + case 'settings': + require_once("settings.php"); + break; - case 'new-user': - require_once("new-user.php"); - break; + case 'new-user': + require_once("new-user.php"); + break; case 'new-service': case 'edit-service': @@ -128,9 +113,9 @@ else{ User::logout(); break; - default: - require_once("dashboard.php"); - break; + default: + require_once("dashboard.php"); + break; } Template::render_footer(true); diff --git a/admin/login-form.php b/admin/login-form.php index f4ef6f9..0521f93 100644 --- a/admin/login-form.php +++ b/admin/login-form.php @@ -1,32 +1,32 @@ -
    -

    -
    -
    - -

    - -

    - -
    -
    - - " class="form-control" name="email" id="email" type="email" tabindex="1" value="" required> -
    -
    - - " class="form-control" name="pass" id="pass" type="password" tabindex="2" required> -
    - - -
    -
    -
    - -
    -
    +
    +

    +
    +
    + +

    + +

    + +
    +
    + + " class="form-control" name="email" id="email" type="email" tabindex="1" value="" required>
    +
    + + " class="form-control" name="pass" id="pass" type="password" tabindex="2" required> +
    + + +
    +
    +
    + +
    +
    +
    -
    -

    -
    -
    - - change_password($_POST['token']); - if (isset($message)){?> -

    - - -

    - - -

    - - -

    - - +

    +
    +
    - if (isset($message)){?> -

    - -
    - - -
    - " type="email" required> - - - -
    - -

    get_name(), $user->get_username());?>

    - - - - " type="password" class="form-control" name="password"> - - " type="password" class="form-control" name="password_repeat"> - - -
    - -
    -change_password($_POST['token']); + if (isset($message)) { ?> +

    + + +

    + + +

    + + +

    + + +

    + +
    + + +
    + " type="email" required> + + + +
    + +

    get_name(), $user->get_username()); ?>

    + + + + " type="password" class="form-control" name="password"> + + " type="password" class="form-control" name="password_repeat"> + + +
    + +
    +
    -

    Add new user

    +

    Add new user

    -
    - -

    - + + +

    +
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    - +
    - -
    + + \ No newline at end of file diff --git a/admin/options.php b/admin/options.php index 3ebdb16..ac7ed0f 100644 --- a/admin/options.php +++ b/admin/options.php @@ -1,15 +1,14 @@ getBooleanSetting($mysqli, "notifyUpdates"); - $emailSubscription_status = $db->getBooleanSetting($mysqli, "subscribe_email"); - $telegramSubscription_status = $db->getBooleanSetting($mysqli, "subscribe_telegram"); - $tg_bot_api_token = $db->getSetting($mysqli, "tg_bot_api_token"); - $tg_bot_username = $db->getSetting($mysqli, "tg_bot_username"); - $php_mailer_status = $db->getBooleanSetting($mysqli, "php_mailer"); - $php_mailer_smtp_status = $db->getBooleanSetting($mysqli, "php_mailer_smtp"); - $php_mailer_secure_status = $db->getBooleanSetting($mysqli, "php_mailer_secure"); - $php_mailer_path = $db->getSetting($mysqli, "php_mailer_path"); - $php_mailer_host = $db->getSetting($mysqli, "php_mailer_host"); - $php_mailer_port = $db->getSetting($mysqli, "php_mailer_port"); - $php_mailer_user = $db->getSetting($mysqli, "php_mailer_user"); - $php_mailer_pass = $db->getSetting($mysqli, "php_mailer_pass"); - $cron_server_ip = $db->getSetting($mysqli, "cron_server_ip"); - $google_rechaptcha_status = $db->getBooleanSetting($mysqli, "google_recaptcha"); - $google_recaptcha_sitekey = $db->getSetting($mysqli, "google_recaptcha_sitekey"); - $google_recaptcha_secret = $db->getSetting($mysqli, "google_recaptcha_secret"); +$db = new SSDB(); +$notifyUpdates_status = $db->getBooleanSetting($mysqli, "notifyUpdates"); +$emailSubscription_status = $db->getBooleanSetting($mysqli, "subscribe_email"); +$telegramSubscription_status = $db->getBooleanSetting($mysqli, "subscribe_telegram"); +$tg_bot_api_token = $db->getSetting($mysqli, "tg_bot_api_token"); +$tg_bot_username = $db->getSetting($mysqli, "tg_bot_username"); +$php_mailer_status = $db->getBooleanSetting($mysqli, "php_mailer"); +$php_mailer_smtp_status = $db->getBooleanSetting($mysqli, "php_mailer_smtp"); +$php_mailer_secure_status = $db->getBooleanSetting($mysqli, "php_mailer_secure"); +$php_mailer_path = $db->getSetting($mysqli, "php_mailer_path"); +$php_mailer_host = $db->getSetting($mysqli, "php_mailer_host"); +$php_mailer_port = $db->getSetting($mysqli, "php_mailer_port"); +$php_mailer_user = $db->getSetting($mysqli, "php_mailer_user"); +$php_mailer_pass = $db->getSetting($mysqli, "php_mailer_pass"); +$cron_server_ip = $db->getSetting($mysqli, "cron_server_ip"); +$google_rechaptcha_status = $db->getBooleanSetting($mysqli, "google_recaptcha"); +$google_recaptcha_sitekey = $db->getSetting($mysqli, "google_recaptcha_sitekey"); +$google_recaptcha_secret = $db->getSetting($mysqli, "google_recaptcha_secret"); - $db->getSetting($mysqli, ""); - $set_post = false; - if(!empty($_POST)){ - $db->updateSetting($mysqli, "notifyUpdates", getToggle($_POST["nu_toggle"])); - $db->updateSetting($mysqli, "name",htmlspecialchars($_POST["sitename"], ENT_QUOTES)); - $db->updateSetting($mysqli, "subscribe_email", getToggle($_POST["email_subscription_toggle"])); - $db->updateSetting($mysqli, "subscribe_telegram", getToggle($_POST["telegram_subscription_toggle"])); - $db->updateSetting($mysqli, "tg_bot_api_token", htmlspecialchars($_POST["tg_bot_api_token"], ENT_QUOTES)); - $db->updateSetting($mysqli, "tg_bot_username", htmlspecialchars($_POST["tg_bot_username"], ENT_QUOTES)); - $db->updateSetting($mysqli, "php_mailer", getToggle($_POST["php_mailer_toggle"])); - $db->updateSetting($mysqli, "php_mailer_smtp", getToggle($_POST["php_mailer_smtp_toggle"])); - $db->updateSetting($mysqli, "php_mailer_secure", getToggle($_POST["php_mailer_secure_toggle"])); - $db->updateSetting($mysqli, "php_mailer_path", htmlspecialchars($_POST["php_mailer_path"], ENT_QUOTES)); - $db->updateSetting($mysqli, "php_mailer_host", htmlspecialchars($_POST["php_mailer_host"], ENT_QUOTES)); - $db->updateSetting($mysqli, "php_mailer_port", htmlspecialchars($_POST["php_mailer_port"], ENT_QUOTES)); - $db->updateSetting($mysqli, "php_mailer_user", htmlspecialchars($_POST["php_mailer_user"], ENT_QUOTES)); - $db->updateSetting($mysqli, "php_mailer_pass", htmlspecialchars($_POST["php_mailer_pass"], ENT_QUOTES)); - $db->updateSetting($mysqli, "cron_server_ip", htmlspecialchars($_POST["cron_server_ip"], ENT_QUOTES)); - $db->updateSetting($mysqli, "google_recaptcha", getToggle($_POST["google_rechaptcha_toggle"])); - $db->updateSetting($mysqli, "google_recaptcha_sitekey", htmlspecialchars($_POST["google_recaptcha_sitekey"], ENT_QUOTES)); - $db->updateSetting($mysqli, "google_recaptcha_secret", htmlspecialchars($_POST["google_recaptcha_secret"], ENT_QUOTES)); +$db->getSetting($mysqli, ""); +$set_post = false; +if (!empty($_POST)) { + $db->updateSetting($mysqli, "notifyUpdates", getToggle($_POST["nu_toggle"])); + $db->updateSetting($mysqli, "name", htmlspecialchars($_POST["sitename"], ENT_QUOTES)); + $db->updateSetting($mysqli, "subscribe_email", getToggle($_POST["email_subscription_toggle"])); + $db->updateSetting($mysqli, "subscribe_telegram", getToggle($_POST["telegram_subscription_toggle"])); + $db->updateSetting($mysqli, "tg_bot_api_token", htmlspecialchars($_POST["tg_bot_api_token"], ENT_QUOTES)); + $db->updateSetting($mysqli, "tg_bot_username", htmlspecialchars($_POST["tg_bot_username"], ENT_QUOTES)); + $db->updateSetting($mysqli, "php_mailer", getToggle($_POST["php_mailer_toggle"])); + $db->updateSetting($mysqli, "php_mailer_smtp", getToggle($_POST["php_mailer_smtp_toggle"])); + $db->updateSetting($mysqli, "php_mailer_secure", getToggle($_POST["php_mailer_secure_toggle"])); + $db->updateSetting($mysqli, "php_mailer_path", htmlspecialchars($_POST["php_mailer_path"], ENT_QUOTES)); + $db->updateSetting($mysqli, "php_mailer_host", htmlspecialchars($_POST["php_mailer_host"], ENT_QUOTES)); + $db->updateSetting($mysqli, "php_mailer_port", htmlspecialchars($_POST["php_mailer_port"], ENT_QUOTES)); + $db->updateSetting($mysqli, "php_mailer_user", htmlspecialchars($_POST["php_mailer_user"], ENT_QUOTES)); + $db->updateSetting($mysqli, "php_mailer_pass", htmlspecialchars($_POST["php_mailer_pass"], ENT_QUOTES)); + $db->updateSetting($mysqli, "cron_server_ip", htmlspecialchars($_POST["cron_server_ip"], ENT_QUOTES)); + $db->updateSetting($mysqli, "google_recaptcha", getToggle($_POST["google_rechaptcha_toggle"])); + $db->updateSetting($mysqli, "google_recaptcha_sitekey", htmlspecialchars($_POST["google_recaptcha_sitekey"], ENT_QUOTES)); + $db->updateSetting($mysqli, "google_recaptcha_secret", htmlspecialchars($_POST["google_recaptcha_secret"], ENT_QUOTES)); - $set_post = true; - /*if($nu_toggle == "yes"){ + $set_post = true; + /*if($nu_toggle == "yes"){ $notifyUpdates_status = true; } else { $notifyUpdates_status = false; }*/ - // TODO - Reload page to prevent showing old values! or update variables being displayed - header("Location: " .$uri = $_SERVER['REQUEST_URI']); - // TODO - The code below will not happen ... + // TODO - Reload page to prevent showing old values! or update variables being displayed + header("Location: " . $uri = $_SERVER['REQUEST_URI']); + // TODO - The code below will not happen ... - /*define("NAME", $db->getSetting($mysqli,"name")); + /*define("NAME", $db->getSetting($mysqli,"name")); define("TITLE", $db->getSetting($mysqli,"title")); define("WEB_URL", $db->getSetting($mysqli,"url")); define("MAILER_NAME", $db->getSetting($mysqli,"mailer")); @@ -92,92 +91,96 @@ else{ define("PHP_MAILER_PASS", $db->getSetting($mysqli,"php_mailer_pass")); define("CRON_SERVER_IP", $db->getSetting($mysqli,"cron_server_ip")); */ - } - Template::render_header(_("Options"), true); +} +Template::render_header(_("Options"), true); ?>
    -

    +

    - -
    -
    - Site Name -
    - + +
    +
    + Site Name
    + +
    - - + + -
    -
    - Telegram BOT API Token -
    - +
    +
    + Telegram BOT API Token
    -
    -
    - Telegram BOT Username -
    - + +
    +
    +
    + Telegram BOT Username
    + +
    - - - -
    -
    - PHPMailer Path -
    - + + + +
    +
    + PHPMailer Path
    -
    -
    - PHPMailer SMTP Host -
    - + +
    +
    +
    + PHPMailer SMTP Host
    -
    -
    - PHPMailer SMTP Port -
    - + +
    +
    +
    + PHPMailer SMTP Port
    -
    -
    - PHPMailer Username -
    - + +
    +
    +
    + PHPMailer Username
    -
    -
    - PHPMailer Password -
    - + +
    +
    +
    + PHPMailer Password
    -
    -
    - Cron Server IP -
    - + +
    +
    +
    + Cron Server IP
    + +
    - -
    -
    - Google reChaptcha Sitekey -
    - + +
    +
    + Google reChaptcha Sitekey
    -
    -
    - Google reChaptcha Secret -
    - + +
    +
    +
    + Google reChaptcha Secret
    + +
    - - + + \ No newline at end of file diff --git a/admin/service-group.php b/admin/service-group.php index 23f3293..6bc4261 100644 --- a/admin/service-group.php +++ b/admin/service-group.php @@ -1,16 +1,13 @@ prepare("SELECT * FROM services_groups WHERE id LIKE ?"); @@ -27,7 +24,7 @@ if ( isset($_GET['id']) && !isset($_POST['id']) ) { $stmt->execute(); $query = $stmt->get_result(); $data = $query->fetch_assoc(); - $group_value = $data['name']; + $group_value = $data['name']; $description_value = $data['description']; $visibility_id_value = $data['visibility']; } @@ -35,55 +32,47 @@ if ( isset($_GET['id']) && !isset($_POST['id']) ) { if (!$boolEdit) { -Template::render_header(_("New service group"), true); ?> -
    -

    -
    + Template::render_header(_("New service group"), true); ?> +
    +

    +
    -

    +

    - -
    - -

    - + + +

    +
    -
    " class="form-control" required>
    -
    " class="form-control">
    +
    " class="form-control" required>
    +
    " class="form-control">
    - + '; + } + ?> + + \ No newline at end of file diff --git a/admin/service.php b/admin/service.php index 1f51d70..0a7a543 100644 --- a/admin/service.php +++ b/admin/service.php @@ -1,11 +1,9 @@ prepare("SELECT * FROM services WHERE id LIKE ?"); @@ -28,7 +26,7 @@ if ( isset($_GET['id']) && !isset($_POST['id']) ) { $query = $stmt->get_result(); $data = $query->fetch_assoc(); //print_r($data); - $service_value = $data['name']; + $service_value = $data['name']; $description_value = $data['description']; $group_id_value = $data['group_id']; } @@ -36,52 +34,46 @@ if ( isset($_GET['id']) && !isset($_POST['id']) ) { if (!$boolEdit) { -Template::render_header(_("New service"), true); ?> -
    -

    -
    + Template::render_header(_("New service"), true); ?> +
    +

    +
    -

    +

    - -
    - -

    - + + +

    +
    -
    " class="form-control" required>
    -
    " class="form-control">
    +
    " class="form-control" required>
    +
    " class="form-control">
    - + '; + } + ?> + + \ No newline at end of file diff --git a/admin/settings.php b/admin/settings.php index bd93f10..309b32f 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -1,10 +1,8 @@ Settings
    -

    - +if (isset($message)) { +?> +

    +
    -

    - get_rank() <= 1){?> -
    -
    - -
    -
    - +

    + get_rank() <= 1) { ?> +
    +
    + +
    +
    +
    - - - - - - get_rank()<=1) - {?> - + + + + + + + get_rank() <= 1) { ?> + query("SELECT services.*, services_groups.name AS group_name FROM `services` LEFT JOIN services_groups ON services.group_id = services_groups.id ORDER BY services.name ASC"); - while($result = $query->fetch_assoc()) - { + while ($result = $query->fetch_assoc()) { echo ""; //echo ""; - echo '"; - echo ""; + echo '"; + echo ""; - if ($user->get_rank()<=1) - { - echo ''; + if ($user->get_rank() <= 1) { + echo ''; } echo ""; - }?> + } ?>
    ".$result['id']."'.$result['name'].''; - echo "".$result['description']."".$result['group_name']."' . $result['name'] . ''; + echo "" . $result['description'] . "" . $result['group_name'] . "
    -

    - get_rank() <= 1){?> -
    -
    - -
    -
    - +

    + get_rank() <= 1) { ?> +
    +
    + +
    +
    +
    - - - - - - - get_rank()<=1) - {?> - + + + + + + + + get_rank() <= 1) { ?> + query("SELECT sg.* , (SELECT COUNT(*) FROM services WHERE services.group_id = sg.id) AS counter FROM services_groups AS sg ORDER BY sg.id ASC"); - while($result = $query->fetch_assoc()) - { + while ($result = $query->fetch_assoc()) { echo ""; //echo ""; - echo '"; - echo ""; + echo '"; + echo ""; - if ($user->get_rank()<=1) - { - echo ''; + if ($user->get_rank() <= 1) { + echo ''; } echo ""; - }?> + } ?>
    ".$result['id']."'.$result['name'].''; - echo ' '.$result['counter'].''; - echo "".$result['description']."".$visibility[$result['visibility']]."' . $result['name'] . ''; + echo ' ' . $result['counter'] . ''; + echo "" . $result['description'] . "" . $visibility[$result['visibility']] . "
    @@ -113,29 +107,38 @@ if (isset($message)){
    -

    - get_rank() == 0){?> +

    + get_rank() == 0) { ?>
    - + + + + + + + + + + + query("SELECT * FROM users"); - while($result = $query->fetch_assoc()) - { + while ($result = $query->fetch_assoc()) { echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; echo ""; - }?> + } ?>
    Active
    Active
    ".$result['id']."".$result['username']."".$result['name']."".$result['surname']."".$result['email']."".$permissions[$result['permission']].""; - echo ""; + echo "" . $result['id'] . "" . $result['username'] . "" . $result['name'] . "" . $result['surname'] . "" . $result['email'] . "" . $permissions[$result['permission']] . ""; + echo ""; echo "
    -
    +
    \ No newline at end of file diff --git a/admin/user.php b/admin/user.php index 04c7ca4..218d2e5 100644 --- a/admin/user.php +++ b/admin/user.php @@ -1,44 +1,37 @@ change_password(); } -if (isset($_POST['username'])) -{ +if (isset($_POST['username'])) { $displayed_user->change_username(); } -if (isset($_POST['name'])) -{ +if (isset($_POST['name'])) { $displayed_user->change_name(); } -if (isset($_POST['email'])) -{ +if (isset($_POST['email'])) { $success = $displayed_user->email_link(); } -if (isset($_POST['permission'])) -{ +if (isset($_POST['permission'])) { $displayed_user->change_permission(); } -if (isset($_GET['what']) && $_GET['what']=='toggle') -{ +if (isset($_GET['what']) && $_GET['what'] == 'toggle') { $displayed_user->toggle(); } @@ -46,19 +39,18 @@ Template::render_header(_("User"), true); ?>
    -

    +

    - -

    + +

    -

    +if (isset($success)) { ?> +

    render_user_settings(); \ No newline at end of file +$displayed_user->render_user_settings(); diff --git a/api/incidents.php b/api/incidents.php index 105509f..06169a4 100644 --- a/api/incidents.php +++ b/api/incidents.php @@ -1,19 +1,17 @@ get_incidents((isset($_GET['future'])?$_GET['future']:false), $offset, $limit, $timestamp); + $result = $constellation->get_incidents((isset($_GET['future']) ? $_GET['future'] : false), $offset, $limit, $timestamp); header('Cache-Control: no-cache'); header('Content-type: application/json'); echo json_encode($result); -} \ No newline at end of file +} diff --git a/api/status.php b/api/status.php index 5ace02d..6a6c7dc 100644 --- a/api/status.php +++ b/api/status.php @@ -1,42 +1,36 @@ render_status(true, false); - echo json_encode($array); - }else{ - $query = $mysqli->prepare("SELECT name FROM services WHERE id=?"); - $query->bind_param("i", $_GET['id']); - $query->execute(); + if (!isset($_GET['id'])) { + $array = $constellation->render_status(true, false); + echo json_encode($array); + } else { + $query = $mysqli->prepare("SELECT name FROM services WHERE id=?"); + $query->bind_param("i", $_GET['id']); + $query->execute(); $result = $query->get_result()->fetch_assoc(); - if (!count($result)) - { - die(json_encode(["error" => _("Service does not exist!")])); + if (!count($result)) { + die(json_encode(["error" => _("Service does not exist!")])); } - $sql = $mysqli->prepare("SELECT type FROM services_status INNER JOIN status ON services_status.status_id = status.id WHERE service_id = ? AND `time` <= ? AND (`end_time` >= ? OR `end_time`=0) ORDER BY `time` DESC LIMIT 1"); + $sql = $mysqli->prepare("SELECT type FROM services_status INNER JOIN status ON services_status.status_id = status.id WHERE service_id = ? AND `time` <= ? AND (`end_time` >= ? OR `end_time`=0) ORDER BY `time` DESC LIMIT 1"); $sql->bind_param("iii", $id, $timestamp, $timestamp); $sql->execute(); $tmp = $sql->get_result(); - if ($tmp->num_rows) - { + if ($tmp->num_rows) { $service = new Service($_GET['id'], $result['name'], $tmp->fetch_assoc()['type']); - } - else{ + } else { $service = new Service($_GET['id'], $result['name']); } echo json_encode($service); } -} \ No newline at end of file +} diff --git a/classes/constellation.php b/classes/constellation.php index f7ab8d0..245bf21 100644 --- a/classes/constellation.php +++ b/classes/constellation.php @@ -6,8 +6,8 @@ require_once(__DIR__ . "/service-group.php"); require_once(__DIR__ . "/user.php"); require_once(__DIR__ . "/token.php"); /** -* Facade class -*/ + * Facade class + */ class Constellation { @@ -18,48 +18,41 @@ class Constellation * @param int $limit - limits the number of incidents rendered * @param Boolean $admin - specifies whether to render admin controls */ - public function render_incidents($future=false, $offset=0, $limit = 5, $admin = 0){ - if ($offset<0) - { + public function render_incidents($future = false, $offset = 0, $limit = 5, $admin = 0) + { + if ($offset < 0) { $offset = 0; } - $limit = (isset($_GET['limit'])?$_GET['limit']:5); - $offset = (isset($_GET['offset'])?$_GET['offset']:0); - $timestamp = (isset($_GET['timestamp']))?$_GET['timestamp']:time(); + $limit = (isset($_GET['limit']) ? $_GET['limit'] : 5); + $offset = (isset($_GET['offset']) ? $_GET['offset'] : 0); + $timestamp = (isset($_GET['timestamp'])) ? $_GET['timestamp'] : time(); $incidents = $this->get_incidents($future, $offset, $limit, $timestamp); $ajax = isset($_GET['ajax']); - if ($future && count($incidents["incidents"]) && !$ajax) - { - echo "

    "._("Planned maintenance")."

    "; - } - else if (count($incidents["incidents"]) &&!$ajax) - { - if ($offset) - { - echo ''; + if ($future && count($incidents["incidents"]) && !$ajax) { + echo "

    " . _("Planned maintenance") . "

    "; + } else if (count($incidents["incidents"]) && !$ajax) { + if ($offset) { + echo ''; } - echo "

    "._("Past incidents")."

    "; - } - else if (!$future &&!$ajax) - { - echo "

    "._("No incidents")."

    "; + echo "

    " . _("Past incidents") . "

    "; + } else if (!$future && !$ajax) { + echo "

    " . _("No incidents") . "

    "; } $show = !$future && $incidents["more"]; $offset += $limit; - if (count($incidents["incidents"])){ + if (count($incidents["incidents"])) { foreach ($incidents['incidents'] as $incident) { $incident->render($admin); } - if ($show) - { - echo ''; + if ($show) { + echo ''; } } } @@ -69,54 +62,49 @@ class Constellation * @param boolean $admin * @return array of services */ - public function render_status($admin = false, $heading = true){ + public function render_status($admin = false, $heading = true) + { global $mysqli; //$query = $mysqli->query("SELECT id, name, description FROM services"); $query = $mysqli->query("SELECT services.id, services.name, services.description, services_groups.name as group_name FROM services LEFT JOIN services_groups ON services.group_id=services_groups.id ORDER BY services_groups.name "); $array = array(); - if ($query->num_rows){ + if ($query->num_rows) { $timestamp = time(); - while($result = $query->fetch_assoc()) - { + while ($result = $query->fetch_assoc()) { $id = $result['id']; $sql = $mysqli->prepare("SELECT type FROM services_status INNER JOIN status ON services_status.status_id = status.id WHERE service_id = ? AND `time` <= ? AND (`end_time` >= ? OR `end_time`=0) ORDER BY `time` DESC LIMIT 1"); $sql->bind_param("iii", $id, $timestamp, $timestamp); $sql->execute(); $tmp = $sql->get_result(); - if ($tmp->num_rows) - { + if ($tmp->num_rows) { $array[] = new Service($result['id'], $result['name'], $result['description'], $result['group_name'], $tmp->fetch_assoc()['type']); - } - else{ + } else { $array[] = new Service($result['id'], $result['name'], $result['description'], $result['group_name']); } } - if ($heading) - { + if ($heading) { echo Service::current_status($array); } - } - else{ + } else { $array[] = new Service(0, _("No services"), -1); } - if (!$admin) - { - ?> + if (!$admin) { +?> - '; //$arrCompletedGroups = array(); - foreach($array as $service){ + foreach ($array as $service) { //print_r($service); //if ( !empty($service->group_name) && !in_array($service->group_name, $arrCompletedGroups)) { -//print $service->name; + //print $service->name; // $arrCompletedGroups[] = $service['group_name']; // $service->render(true); //} else { @@ -125,35 +113,33 @@ class Constellation } echo ''; //echo '
    '; - } - else{ + } else { return $array; } } - function get_incidents($future = false, $offset = 0, $limit = 5, $timestamp = 0){ + function get_incidents($future = false, $offset = 0, $limit = 5, $timestamp = 0) + { global $mysqli; - if ($timestamp == 0) - { + if ($timestamp == 0) { $timestamp = time(); } - $operator = ($future)?">=":"<="; + $operator = ($future) ? ">=" : "<="; $limit++; $sql = $mysqli->prepare("SELECT users.id, status.type, status.title, status.text, status.time, status.end_time, users.username, status.id as status_id FROM status INNER JOIN users ON user_id=users.id WHERE `time` $operator ? AND `end_time` $operator ? OR (`time`<=? AND `end_time` $operator ? ) ORDER BY `time` DESC LIMIT ? OFFSET ?"); - $sql->bind_param("iiiiii",$timestamp, $timestamp, $timestamp, $timestamp, $limit, $offset); + $sql->bind_param("iiiiii", $timestamp, $timestamp, $timestamp, $timestamp, $limit, $offset); $sql->execute(); $query = $sql->get_result(); $array = []; $limit--; $more = false; - if ($query->num_rows>$limit){ + if ($query->num_rows > $limit) { $more = true; } - if ($query->num_rows){ - while(($result = $query->fetch_assoc()) && $limit-- > 0) - { + if ($query->num_rows) { + while (($result = $query->fetch_assoc()) && $limit-- > 0) { // Add service id and service names to an array in the Incident class $stmt_service = $mysqli->prepare("SELECT services.id,services.name FROM services INNER JOIN services_status ON services.id = services_status.service_id @@ -161,7 +147,7 @@ class Constellation $stmt_service->bind_param("i", $result['status_id']); $stmt_service->execute(); $query_service = $stmt_service->get_result(); - while($result_service = $query_service->fetch_assoc()) { + while ($result_service = $query_service->fetch_assoc()) { $result['service_id'][] = $result_service['id']; $result['service_name'][] = $result_service['name']; } @@ -198,15 +184,14 @@ class Constellation function render_alert($alert_type, $header, $message, $show_link = false, $url = null, $link_text = null) { echo '

    - '; - if ( $show_link ) { - echo ''; + if ($show_link) { + echo ''; } - } } diff --git a/classes/db-class.php b/classes/db-class.php index b9fe130..c104916 100644 --- a/classes/db-class.php +++ b/classes/db-class.php @@ -3,53 +3,57 @@ class SSDB { - function execute($conn,$sql){ + function execute($conn, $sql) + { if ($conn->query($sql) === TRUE) { - return true; + return true; } else { - return $conn->error; + return $conn->error; } } - function getSetting($conn,$setting){ - $sql = "SELECT value FROM settings WHERE setting='".$setting."'"; + function getSetting($conn, $setting) + { + $sql = "SELECT value FROM settings WHERE setting='" . $setting . "'"; $result = $conn->query($sql); if ($result->num_rows == 1) { - while($row = $result->fetch_assoc()) { + while ($row = $result->fetch_assoc()) { return $row["value"]; } } else { return "null"; } } - function setSetting($conn,$settingname,$settingvalue){ - $sql = "INSERT INTO settings (setting,value) VALUES ('".$settingname."','".$settingvalue."');"; - if ($conn->query($sql) === TRUE) { - return true; - } else { - return $conn->error; - } - - } - function deleteSetting($conn,$settingname){ - $sql = "DELETE FROM settings WHERE setting=\"".$settingname."\";"; + function setSetting($conn, $settingname, $settingvalue) + { + $sql = "INSERT INTO settings (setting,value) VALUES ('" . $settingname . "','" . $settingvalue . "');"; if ($conn->query($sql) === TRUE) { - return true; - } else { - return $conn->error; - } - + return true; + } else { + return $conn->error; + } } - function updateSetting($conn, $settingname, $settingvalue){ + function deleteSetting($conn, $settingname) + { + $sql = "DELETE FROM settings WHERE setting=\"" . $settingname . "\";"; + if ($conn->query($sql) === TRUE) { + return true; + } else { + return $conn->error; + } + } + function updateSetting($conn, $settingname, $settingvalue) + { $this->deleteSetting($conn, $settingname); $this->setSetting($conn, $settingname, $settingvalue); return true; } - function getBooleanSetting($conn, $setting) { - if (trim($this->getSetting($conn, $setting)) == "yes"){ - return true; - } - return false; + function getBooleanSetting($conn, $setting) + { + if (trim($this->getSetting($conn, $setting)) == "yes") { + return true; + } + return false; } } diff --git a/classes/incident.php b/classes/incident.php index 8f48b3b..503d827 100644 --- a/classes/incident.php +++ b/classes/incident.php @@ -2,8 +2,8 @@ require_once(__DIR__ . "/notification.php"); /** -* Class for creating and rendering an incident -*/ + * Class for creating and rendering an incident + */ class Incident implements JsonSerializable { private $id; @@ -24,14 +24,14 @@ class Incident implements JsonSerializable */ function __construct($data) { - //TODO: Maybe get data from id? + //TODO: Maybe get data from id? $this->id = $data['status_id']; $this->timestamp = $data['time']; $this->end_timestamp = $data['end_time']; - $this->date = new DateTime("@".$data['time']); + $this->date = new DateTime("@" . $data['time']); $this->date = $this->date->format('Y-m-d H:i:sP'); - if ($data['end_time']>0){ - $this->end_date = new DateTime("@".$data['end_time']); + if ($data['end_time'] > 0) { + $this->end_date = new DateTime("@" . $data['end_time']); $this->end_date = $this->end_date->format('Y-m-d H:i:sP'); } $this->type = $data['type']; @@ -46,17 +46,16 @@ class Incident implements JsonSerializable * Deletes incident by ID. * @param int ID */ - public static function delete($id){ + public static function delete($id) + { global $mysqli, $message, $user; - if ($user->get_rank() > 1) - { + if ($user->get_rank() > 1) { $stmt = $mysqli->prepare("SELECT count(*) as count FROM status WHERE id= ? AND user_id = ?"); $stmt->bind_param("ii", $id, $_SESSION['user']); $stmt->execute(); $query = $stmt->get_result(); - if (!$query->fetch_assoc()['count']) - { + if (!$query->fetch_assoc()['count']) { $message = _("You don't have permission to do that!"); return; } @@ -71,7 +70,7 @@ class Incident implements JsonSerializable $stmt->bind_param("i", $id); $stmt->execute(); $query = $stmt->get_result(); - header("Location: ".WEB_URL."/admin"); + header("Location: " . WEB_URL . "/admin"); } /** @@ -84,77 +83,66 @@ class Incident implements JsonSerializable { global $mysqli, $message; //Sould be a better way to get this array... - $statuses = array(_("Major outage"), _("Minor outage"), _("Planned maintenance"), _("Operational") ); + $statuses = array(_("Major outage"), _("Minor outage"), _("Planned maintenance"), _("Operational")); $user_id = $_SESSION['user']; $type = $_POST['type']; $title = strip_tags($_POST['title']); $text = strip_tags($_POST['text'], '
    '); - if (strlen($title)==0) - { + if (strlen($title) == 0) { $message = _("Please enter title"); return; - }else if(strlen($title)>50){ + } else if (strlen($title) > 50) { $message = _("Title too long! Character limit is 50"); return; } - if (strlen($title)==0) - { + if (strlen($title) == 0) { $message = _("Please enter text"); return; } - if ($type == 2 && (!strlen(trim($_POST['time'])) || !strlen(trim($_POST['end_time'])))) - { + if ($type == 2 && (!strlen(trim($_POST['time'])) || !strlen(trim($_POST['end_time'])))) { $message = _("Please set start and end time! Use ISO 8601 format."); return; } - if (empty($_POST['services'])){ + if (empty($_POST['services'])) { $message = _("Please select at least one service"); - } - else - { - if (!is_array($_POST['services'])) - { + } else { + if (!is_array($_POST['services'])) { $services = array($_POST['services']); - } - else - { + } else { $services = $_POST['services']; } - if (!empty($_POST['time']) && $type == 2){ - $input_time = (!empty($_POST['time_js'])?$_POST['time_js']: $_POST['time']); - $input_end_time = (!empty($_POST['end_time_js'])?$_POST['end_time_js']: $_POST['end_time']); + if (!empty($_POST['time']) && $type == 2) { + $input_time = (!empty($_POST['time_js']) ? $_POST['time_js'] : $_POST['time']); + $input_end_time = (!empty($_POST['end_time_js']) ? $_POST['end_time_js'] : $_POST['end_time']); $time = strtotime($input_time); $end_time = strtotime($input_end_time); - if (!$time) - { + if (!$time) { $message = _("Start date format is not recognized. Please use ISO 8601 format."); return; } - if (!$end_time) - { + if (!$end_time) { $message = _("End date format is not recognized. Please use ISO 8601 format."); return; } - if ($time >= $end_time) - { + if ($time >= $end_time) { $message = _("End time is either the same or earlier than start time!"); return; } - }else{ + } else { $time = time(); $end_time = ''; } $stmt = $mysqli->prepare("INSERT INTO status VALUES (NULL,?, ?, ?, ?, ?, ?)"); - $stmt->bind_param("issiii", $type, $title, $text, $time ,$end_time ,$user_id); + $stmt->bind_param("issiii", $type, $title, $text, $time, $end_time, $user_id); $stmt->execute(); $query = $stmt->get_result(); $status_id = $mysqli->insert_id; @@ -178,7 +166,7 @@ class Incident implements JsonSerializable $notify->notify_subscribers(); - header("Location: ".WEB_URL."/admin?sent=true"); + header("Location: " . WEB_URL . "/admin?sent=true"); } } @@ -187,40 +175,42 @@ class Incident implements JsonSerializable * @param Boolean $admin - decides whether admin controls should be rendered * @return void */ - public function render($admin=0){ + public function render($admin = 0) + { global $icons; global $classes, $user; - $admin = $admin && (($user->get_rank()<=1) || ($user->get_username() == $this->username)); + $admin = $admin && (($user->get_rank() <= 1) || ($user->get_username() == $this->username)); $Parsedown = new Parsedown(); - ?> -
    -
    -
    - title; ?> - -
    - id.'" class="pull-right delete">'; - }?> -
    +?> +
    +
    +
    + title; ?> + +
    + id . '" class="pull-right delete">'; + } ?> +
    -
    - setBreaksEnabled(true)->text($this->text); ?> -
    - -
    - + setBreaksEnabled(true)->text($this->text); ?> +
    + +
    + $this->id, "date" => $this->timestamp, diff --git a/classes/locale-negotiator.php b/classes/locale-negotiator.php index b13ee23..e234cd2 100644 --- a/classes/locale-negotiator.php +++ b/classes/locale-negotiator.php @@ -1,10 +1,11 @@ '中文', 'zh_TW' => '中文', 'zu_ZA' => 'Isizulu', - ); + ); /** - * This method scans for languages and creates a list of language and its name (localized ofc.) - * @param String $default_language language displayed to user in case no suitable lang is found - */ + * This method scans for languages and creates a list of language and its name (localized ofc.) + * @param String $default_language language displayed to user in case no suitable lang is found + */ function __construct($default_language) { - $tmp = glob(__DIR__ . '/../locale/*' , GLOB_ONLYDIR); + $tmp = glob(__DIR__ . '/../locale/*', GLOB_ONLYDIR); $this->default_language = $default_language; //Works only if the server supports the locale //This basically means $accepted_langs[] = ""; @@ -239,41 +240,42 @@ class LocaleNegotiator } /** - * Returns list of accepted langs so it can be reused for rendering language list for switching... - */ - public function get_accepted_langs(){ + * Returns list of accepted langs so it can be reused for rendering language list for switching... + */ + public function get_accepted_langs() + { return $this->accepted_langs; } /** - * This method does the actual negotiation. It has override parameter in case user wants to switch - * languages. - * @param String $override adds language to list of preffered languages with highest priority - * @return String language code that matched best with browser preferences - */ - public function negotiate($override = null){ + * This method does the actual negotiation. It has override parameter in case user wants to switch + * languages. + * @param String $override adds language to list of preffered languages with highest priority + * @return String language code that matched best with browser preferences + */ + public function negotiate($override = null) + { $langs = []; if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $http_accept_language = str_replace("-", "_", $_SERVER['HTTP_ACCEPT_LANGUAGE']); - preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $http_accept_language, $lang_parse); + preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $http_accept_language, $lang_parse); - if (count($lang_parse[1])) { - $langs = array_combine($lang_parse[1], $lang_parse[4]); - - foreach ($langs as $lang => $val) { - //If browser didn't send quality of language, it is 1 by default - if ($val === '') $langs[$lang] = 1; - } + if (count($lang_parse[1])) { + $langs = array_combine($lang_parse[1], $lang_parse[4]); - if (isset($override)) - { - //More important than the best lang of browser - $langs[$override] = 2; - } + foreach ($langs as $lang => $val) { + //If browser didn't send quality of language, it is 1 by default + if ($val === '') $langs[$lang] = 1; + } - arsort($langs, SORT_NUMERIC); - } + if (isset($override)) { + //More important than the best lang of browser + $langs[$override] = 2; + } + + arsort($langs, SORT_NUMERIC); + } } //So we have lang code as value @@ -285,18 +287,18 @@ class LocaleNegotiator global $lang; foreach ($langs as $lang) { - if (strlen($lang)>2){ - if (in_array($lang, $accepted_langs)){ + if (strlen($lang) > 2) { + if (in_array($lang, $accepted_langs)) { $best_match = $lang; break; } - }else{ - $possible = array_filter($accepted_langs, function($key) { + } else { + $possible = array_filter($accepted_langs, function ($key) { global $lang; - return strpos($key, $lang) === 0; + return strpos($key, $lang) === 0; }); - if (count($possible)){ + if (count($possible)) { foreach ($possible as $value) { $best_match = $value; } @@ -305,11 +307,10 @@ class LocaleNegotiator } } - if ($best_match === false){ + if ($best_match === false) { $best_match = $this->default_language; } return $best_match; } } - diff --git a/classes/mailer.php b/classes/mailer.php index 4a716b6..9edf1b1 100644 --- a/classes/mailer.php +++ b/classes/mailer.php @@ -15,10 +15,11 @@ if (file_exists("libs/php_idn/idna.php")) { require_once("../libs/php_idn/idna.php"); } -class Mailer { - - public function __construct(){ +class Mailer +{ + public function __construct() + { } /** @@ -28,7 +29,8 @@ class Mailer { * @param boolean $html Set to true if we are sending HTML Mailer * @return boolean True if success */ - public function send_mail($to, $subject, $message, $html = true) { + public function send_mail($to, $subject, $message, $html = true) + { // TODO -Handle $to as an array in order to send to muliple recipients without having // to call the entire send_mail function over and over.. @@ -36,19 +38,19 @@ class Mailer { // Convert IDN/punycode domain to ascii // TODO Handle IDN in left hand side of email address - if ( $this->is_utf8($to) ) { + if ($this->is_utf8($to)) { $elements = explode('@', $to); $domainpart = EncodePunycodeIDN(array_pop($elements)); // Convert domain part to ascii $to = $elements[0] . '@' . $domainpart; // Reassemble tge full email address } // Send using PHP mailer if it is enabled - if ( PHP_MAILER ) { - require_once(PHP_MAILER_PATH .'/Exception.php'); /* Exception class. */ - require_once(PHP_MAILER_PATH .'/PHPMailer.php'); /* The main PHPMailer class. */ + if (PHP_MAILER) { + require_once(PHP_MAILER_PATH . '/Exception.php'); /* Exception class. */ + require_once(PHP_MAILER_PATH . '/PHPMailer.php'); /* The main PHPMailer class. */ - if ( PHP_MAILER_SMTP ) { - require_once(PHP_MAILER_PATH .'/SMTP.php'); /* SMTP class, needed if you want to use SMTP. */ + if (PHP_MAILER_SMTP) { + require_once(PHP_MAILER_PATH . '/SMTP.php'); /* SMTP class, needed if you want to use SMTP. */ } $phpmail = new PHPMailer(false); @@ -58,7 +60,7 @@ class Mailer { //$phpmail->Debugoutput = error_log; // Define SMTP parameters if enabled - if ( PHP_MAILER_SMTP ) { + if (PHP_MAILER_SMTP) { $phpmail->isSMTP(); $phpmail->Host = PHP_MAILER_HOST; @@ -67,7 +69,7 @@ class Mailer { //$phpmail->SMTPDebug = 2; // Enable for debugging // Handle authentication for SMTP if enabled - if ( !empty(PHP_MAILER_USER) ) { + if (!empty(PHP_MAILER_USER)) { $phpmail->SMTPAuth = true; $phpmail->Username = PHP_MAILER_USER; $phpmail->Password = PHP_MAILER_PASS; @@ -77,7 +79,7 @@ class Mailer { $phpmail->addAddress($to); $phpmail->Subject = $subject; // Send HMTL mail - if ( $html ) { + if ($html) { $phpmail->msgHtml($message); $phpmail->AltBody = $this->convert_html_to_plain_txt($message, false); } else { @@ -85,24 +87,22 @@ class Mailer { } $phpmail->isHtml($html); // use htmlmail if enabled - if ( ! $phpmail->send() ) { + if (!$phpmail->send()) { // TODO Log error message $phpmail->ErrorInfo; return false; } return true; - } else { // Use standard PHP mail() function - $headers = "Content-Type: $content_type; \"charset=utf-8\" ".PHP_EOL; - $headers .= "MIME-Version: 1.0 ".PHP_EOL; - $headers .= "From: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; - $headers .= "Reply-To: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; + $headers = "Content-Type: $content_type; \"charset=utf-8\" " . PHP_EOL; + $headers .= "MIME-Version: 1.0 " . PHP_EOL; + $headers .= "From: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; + $headers .= "Reply-To: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; mail($to, $subject, $message, $headers); // TODO log error message if mail fails return true; } - } /** * Tries to verify the domain using dns request against an MX record of the domain part @@ -112,11 +112,12 @@ class Mailer { * @param String $email Email address to check * @return boolean True if MX record exits, false if otherwise */ - public function verify_domain($email){ + public function verify_domain($email) + { // TODO - Handle idn/punycode domain names without being dependent on PHP native libs. $domain = explode('@', $email); - $domain = EncodePunycodeIDN(array_pop($domain).'.'); // Add dot at end of domain to avoid local domain lookups - syslog(1,$domain); + $domain = EncodePunycodeIDN(array_pop($domain) . '.'); // Add dot at end of domain to avoid local domain lookups + syslog(1, $domain); return checkdnsrr($domain, 'MX'); } @@ -145,20 +146,22 @@ class Mailer { * @param boolean $remove_links Set to true if links should be removed from email * @return String pain text version */ - public function convert_html_to_plain_txt($content, $remove_links=false){ + public function convert_html_to_plain_txt($content, $remove_links = false) + { // TODO does not handle unsubscribe/manage subscription text very well. // Replace HTML line breaks with text line breaks - $plain_text = str_ireplace(array("
    ","
    "), "\n\r", $content); + $plain_text = str_ireplace(array("
    ", "
    "), "\n\r", $content); // Remove the content between the tags that wouldn't normally get removed with the strip_tags function - $plain_text = preg_replace(array('@]*?>.*?@siu', + $plain_text = preg_replace(array( + '@]*?>.*?@siu', '@]*?>.*?@siu', '@]*?.*?@siu', '@]*?.*?@siu', ), "", $plain_text); // Remove everything from between the tags that doesn't get removed with strip_tags function // If the user has chosen to preserve the addresses from links - if(!$remove_links){ + if (!$remove_links) { $plain_text = strip_tags(preg_replace('//', ' $1 ', $plain_text)); } @@ -166,9 +169,8 @@ class Mailer { $plain_text = str_replace(" ", "", $plain_text); // Replace multiple line breaks with a single line break - $plain_text = preg_replace("/(\s){3,}/","\r\n\r\n",trim($plain_text)); + $plain_text = preg_replace("/(\s){3,}/", "\r\n\r\n", trim($plain_text)); return $plain_text; } - } diff --git a/classes/notification.php b/classes/notification.php index 762bbd7..8ce257a 100644 --- a/classes/notification.php +++ b/classes/notification.php @@ -25,7 +25,7 @@ class Notification public function populate_impacted_services($status_id) { global $mysqli; - if (! empty($status_id)) { + if (!empty($status_id)) { // Fetch services names for use in email $stmt = $mysqli->prepare("SELECT services.id, services.name FROM services INNER JOIN services_status on services.id = services_status.service_id WHERE services_status.status_id = ?"); $stmt->bind_param("i", $status_id); @@ -66,7 +66,7 @@ class Notification $queue->user_id = $_SESSION['user']; $arr_data = array(); - if ( SUBSCRIBE_EMAIL ) { + if (SUBSCRIBE_EMAIL) { $arr_data = $this->prepare_email(); // Make up the base message and subject for email $queue->type_id = $queue->all_type_id['notify_email']; $queue->template_data1 = $arr_data['subject']; @@ -75,7 +75,7 @@ class Notification //syslog(1, "queue email: ". $task_id_email); $arr_email = array(); } - if ( SUBSCRIBE_TELEGRAM ) { + if (SUBSCRIBE_TELEGRAM) { $arr_data = $this->prepare_telegram(); $queue->type_id = $queue->all_type_id['notify_telegram']; $queue->template_data1 = null; @@ -103,16 +103,14 @@ class Notification if ($typeID == 2 && SUBSCRIBE_EMAIL) { $arr_email[] = $subscriber['subscriberIDFK']; } - } - } - if ( SUBSCRIBE_TELEGRAM) { + if (SUBSCRIBE_TELEGRAM) { $queue->task_id = $task_id_telegram; $queue->add_notification($arr_telegram); // Add array of Telegram users to the notification queue list } - if ( SUBSCRIBE_EMAIL ) { + if (SUBSCRIBE_EMAIL) { $queue->task_id = $task_id_email; $queue->add_notification($arr_email); // Add array of Email users to the notification queue list } @@ -132,13 +130,12 @@ class Notification $msg = sprintf($msg, $firstname); $tg_message = array('text' => $msg, 'chat_id' => $userID, 'parse_mode' => 'HTML'); - $json = @file_get_contents("https://api.telegram.org/bot" . TG_BOT_API_TOKEN . "/sendMessage?" . http_build_query($tg_message) ); + $json = @file_get_contents("https://api.telegram.org/bot" . TG_BOT_API_TOKEN . "/sendMessage?" . http_build_query($tg_message)); $response = json_decode($json, true); - if (!is_array($response) || ! array_key_exists("ok", $response) || $response['ok'] != 1 ) { + if (!is_array($response) || !array_key_exists("ok", $response) || $response['ok'] != 1) { return false; - } return true; } @@ -154,13 +151,14 @@ class Notification { // TODO Error handling $mailer = new Mailer(); - if ( ! $mailer->send_mail($subscriber, $subject, $msg, true) ) { - return false; + if (!$mailer->send_mail($subscriber, $subject, $msg, true)) { + return false; } return true; } - public function prepare_email(){ + public function prepare_email() + { $Parsedown = new Parsedown(); $str_mail = file_get_contents("../libs/templates/email_status_update.html"); @@ -189,7 +187,8 @@ class Notification return $val; } - public function prepare_telegram(){ + public function prepare_telegram() + { $msg = _("Hi #s!\nThere is a status update for service(s): %s\nThe new status is: %s\nTitle: %s\n\n%s\n\nView online"); $val['body'] = sprintf($msg, $this->servicenames, $this->status, $this->title, $this->text, WEB_URL); return $val; diff --git a/classes/queue.php b/classes/queue.php index dd8187c..f989c56 100644 --- a/classes/queue.php +++ b/classes/queue.php @@ -5,157 +5,167 @@ */ class Queue { - public $task_id; - public $type_id; - public $status; - public $template_data1; // i.e. Subject for email - public $template_data2; // i.e. HTML email body - public $create_time; - public $completed_time; - public $num_errors; - public $user_id; - public $all_type_id = array('notify_telegram' => 1, - 'notify_email' => 2); + public $task_id; + public $type_id; + public $status; + public $template_data1; // i.e. Subject for email + public $template_data2; // i.e. HTML email body + public $create_time; + public $completed_time; + public $num_errors; + public $user_id; + public $all_type_id = array( + 'notify_telegram' => 1, + 'notify_email' => 2 + ); - public $all_status = array('populating' => 1, - 'ready' => 2, - 'processing' => 3, - 'completed' => 4, - 'failed' => 5); + public $all_status = array( + 'populating' => 1, + 'ready' => 2, + 'processing' => 3, + 'completed' => 4, + 'failed' => 5 + ); - public function add_task() { - global $mysqli; - $stmt = $mysqli->prepare("INSERT INTO queue_task (type_id, status, template_data1, template_data2, created_time, user_id) VALUES (?,?,?,?,?,?)"); - if ( false===$stmt ) { - //die('prepare() failed: ' . htmlspecialchars($mysqli->error)); - echo $mysqli->errno(); - - } - #if ( false === $stmt ) { syslog(1, "Error :". $mysqli->error); } - $now = time(); - $res = $stmt->bind_param("iissii", $this->type_id, $this->status, $this->template_data1, $this->template_data2, $now, $this->user_id); - if ( false === $res ) { - echo "error"; - die(); - } - $stmt->execute(); - $query = $stmt->get_result(); - print $query; - $this->task_id = $mysqli->insert_id; - return $this->task_id; + public function add_task() + { + global $mysqli; + $stmt = $mysqli->prepare("INSERT INTO queue_task (type_id, status, template_data1, template_data2, created_time, user_id) VALUES (?,?,?,?,?,?)"); + if (false === $stmt) { + //die('prepare() failed: ' . htmlspecialchars($mysqli->error)); + echo $mysqli->errno(); } - - /** - * Remove task from the queue - * @return void - */ - public function delete_task($task_id){ - global $mysqli; - $stmt = $mysqli->prepare("DELETE FROM queue_task WHERE id = ?"); - $stmt->bind_param("i", $task_id); - $stmt->execute(); + #if ( false === $stmt ) { syslog(1, "Error :". $mysqli->error); } + $now = time(); + $res = $stmt->bind_param("iissii", $this->type_id, $this->status, $this->template_data1, $this->template_data2, $now, $this->user_id); + if (false === $res) { + echo "error"; + die(); } + $stmt->execute(); + $query = $stmt->get_result(); + print $query; + $this->task_id = $mysqli->insert_id; + return $this->task_id; + } - /** - * Update status for given task - * @param int $new_status The new current status of the task. Must be selected from the $all_status array. - * @return void - */ - public function set_task_status($new_status) { - global $mysqli; - $stmt = $mysqli->prepare("UPDATE queue_task SET status = ? WHERE id = ?"); - $stmt->bind_param("ii", $new_status, $this->task_id); - $stmt->execute(); - $this->status = $new_status; + /** + * Remove task from the queue + * @return void + */ + public function delete_task($task_id) + { + global $mysqli; + $stmt = $mysqli->prepare("DELETE FROM queue_task WHERE id = ?"); + $stmt->bind_param("i", $task_id); + $stmt->execute(); + } + + /** + * Update status for given task + * @param int $new_status The new current status of the task. Must be selected from the $all_status array. + * @return void + */ + public function set_task_status($new_status) + { + global $mysqli; + $stmt = $mysqli->prepare("UPDATE queue_task SET status = ? WHERE id = ?"); + $stmt->bind_param("ii", $new_status, $this->task_id); + $stmt->execute(); + $this->status = $new_status; + } + + /** + * Add notification queue data for given task + * @param array $arr_data Array filled with subscriber_id + * @return void + */ + public function add_notification($arr_data) + { + global $mysqli; + + //Default status = 1, retres = 0, task_id = $this->task_id + + // Build query manually since mysqli doesn't cater well for multi insert.. + $count = count($arr_data); // Let's find number of elements + $counter = 0; + $query = ''; + $seperator = ','; + $sub_query = '(%d, %d, %d ,%d)%s'; + + foreach ($arr_data as $value) { + $counter++; + if ($counter == $count) { + $seperator = ''; + } // Make sure last character for SQL query is correct + $query .= sprintf($sub_query, $this->task_id, 1, $value, 0, $seperator); } + $sql = "INSERT INTO queue_notify (task_id, status, subscriber_id, retries) VALUES " . $query; - /** - * Add notification queue data for given task - * @param array $arr_data Array filled with subscriber_id - * @return void - */ - public function add_notification($arr_data) { - global $mysqli; + $mysqli->query($sql); - //Default status = 1, retres = 0, task_id = $this->task_id + $this->set_task_status($this->all_status['ready']); // Make task available for release + } - // Build query manually since mysqli doesn't cater well for multi insert.. - $count = count($arr_data); // Let's find number of elements - $counter = 0; - $query = ''; - $seperator = ','; - $sub_query = '(%d, %d, %d ,%d)%s'; + public function update_notification_retries($task_id, $subscriber_id) + { + global $mysqli; + $stmt = $mysqli->prepare("UPDATE queue_notify SET retries = retries+1 WHERE task_id = ? AND subscriber_id = ?"); + $stmt->bind_param("ii", $task_id, $subscriber_id); + $stmt->execute(); + } - foreach ($arr_data as $value) { - $counter++; - if ($counter == $count) { $seperator = ''; } // Make sure last character for SQL query is correct - $query .= sprintf($sub_query, $this->task_id, 1, $value, 0, $seperator); - } - $sql = "INSERT INTO queue_notify (task_id, status, subscriber_id, retries) VALUES ". $query; + public function delete_notification($task_id, $subscriber_id) + { + global $mysqli; + $stmt = $mysqli->prepare("DELETE FROM queue_notify WHERE task_id = ? AND subscriber_id = ?"); + $stmt->bind_param("ii", $task_id, $subscriber_id); + $stmt->execute(); + } - $mysqli->query($sql); + // TODO: Fix max attempts for notifications + public function process_queue() + { + global $mysqli; + $stmt = $mysqli->query("SELECT qn.id, qn.task_id, qn.status, qn.subscriber_id, qn.retries, sub.firstname, sub.userID, sub.token FROM queue_notify AS qn INNER JOIN subscribers AS sub ON qn.subscriber_id = sub.subscriberID WHERE qn.status NOT LIKE 2 AND sub.active=1"); + while ($result = $stmt->fetch_assoc()) { - $this->set_task_status($this->all_status['ready']); // Make task available for release - } + $i = 2; + $stmt2 = $mysqli->prepare("SELECT * FROM queue_task WHERE id = ? AND status = ?"); + $stmt2->bind_param("ii", $result['task_id'], $i); + $stmt2->execute(); + $tmp = $stmt2->get_result(); + $result2 = $tmp->fetch_assoc(); + $typeID = $result2['type_id']; - public function update_notification_retries($task_id, $subscriber_id) { - global $mysqli; - $stmt = $mysqli->prepare("UPDATE queue_notify SET retries = retries+1 WHERE task_id = ? AND subscriber_id = ?"); - $stmt->bind_param("ii", $task_id, $subscriber_id); - $stmt->execute(); - } - - public function delete_notification($task_id, $subscriber_id) { - global $mysqli; - $stmt = $mysqli->prepare("DELETE FROM queue_notify WHERE task_id = ? AND subscriber_id = ?"); - $stmt->bind_param("ii", $task_id, $subscriber_id); - $stmt->execute(); - - } - - // TODO: Fix max attempts for notifications - public function process_queue(){ - global $mysqli; - $stmt = $mysqli->query("SELECT qn.id, qn.task_id, qn.status, qn.subscriber_id, qn.retries, sub.firstname, sub.userID, sub.token FROM queue_notify AS qn INNER JOIN subscribers AS sub ON qn.subscriber_id = sub.subscriberID WHERE qn.status NOT LIKE 2 AND sub.active=1"); - while ( $result = $stmt->fetch_assoc() ) { - - $i = 2; - $stmt2 = $mysqli->prepare("SELECT * FROM queue_task WHERE id = ? AND status = ?"); - $stmt2->bind_param("ii", $result['task_id'], $i); - $stmt2->execute(); - $tmp = $stmt2->get_result(); - $result2 = $tmp->fetch_assoc(); - $typeID = $result2['type_id']; - - // Handle telegram - if ($typeID == 1) { - $msg = str_replace("#s", $result['firstname'], $result2['template_data2']); - if ( ! Notification::submit_queue_telegram($result['userID'], $result['firstname'], $msg) ) { - Queue::update_notification_retries($result['task_id'], $result['subscriber_id']); // Sent - } else { - Queue::delete_notification($result['task_id'], $result['subscriber_id']); // Failed - } - } - - // Handle email - if ($typeID == 2) { - $msg = str_replace("%token%", $result['token'], $result2['template_data2']); - if ( ! Notification::submit_queue_email($result['userID'], $result2['template_data1'], $msg) ) { - Queue::update_notification_retries($result['task_id'], $result['subscriber_id']); // Sent - - } else { - Queue::delete_notification($result['task_id'], $result['subscriber_id']); // Failed - } - } - } - - // Check if queue log is empty and if so delete the queue_task - $stmt = $mysqli->query("SELECT id, (SELECT COUNT(*) FROM queue_notify AS qn WHERE qn.task_id = queue_task.id) AS count FROM queue_task"); - while ( $result = $stmt->fetch_assoc() ) { - if ( $result['count'] == 0 ) { - Queue::delete_task($result['id']); + // Handle telegram + if ($typeID == 1) { + $msg = str_replace("#s", $result['firstname'], $result2['template_data2']); + if (!Notification::submit_queue_telegram($result['userID'], $result['firstname'], $msg)) { + Queue::update_notification_retries($result['task_id'], $result['subscriber_id']); // Sent + } else { + Queue::delete_notification($result['task_id'], $result['subscriber_id']); // Failed } } + // Handle email + if ($typeID == 2) { + $msg = str_replace("%token%", $result['token'], $result2['template_data2']); + if (!Notification::submit_queue_email($result['userID'], $result2['template_data1'], $msg)) { + Queue::update_notification_retries($result['task_id'], $result['subscriber_id']); // Sent + + } else { + Queue::delete_notification($result['task_id'], $result['subscriber_id']); // Failed + } + } } + + // Check if queue log is empty and if so delete the queue_task + $stmt = $mysqli->query("SELECT id, (SELECT COUNT(*) FROM queue_notify AS qn WHERE qn.task_id = queue_task.id) AS count FROM queue_task"); + while ($result = $stmt->fetch_assoc()) { + if ($result['count'] == 0) { + Queue::delete_task($result['id']); + } + } + } } diff --git a/classes/service-group.php b/classes/service-group.php index 933571a..a22a6f4 100644 --- a/classes/service-group.php +++ b/classes/service-group.php @@ -1,7 +1,8 @@ 50) - { + if (strlen($_POST['group']) > 50) { $message = _("Service group name is too long! Character limit is 50"); return; - }else if (strlen(trim($_POST['group']))==0){ + } else if (strlen(trim($_POST['group'])) == 0) { $message = _("Please enter name!"); return; } - if ($user->get_rank()<=1) - { + if ($user->get_rank() <= 1) { global $mysqli; $name = $_POST["group"]; $description = $_POST["description"]; @@ -82,9 +81,8 @@ class ServiceGroup $stmt->bind_param("ssi", $name, $description, $visibility_id); $stmt->execute(); $stmt->get_result(); - header("Location: ".WEB_URL."/admin/?do=settings"); - }else - { + header("Location: " . WEB_URL . "/admin/?do=settings"); + } else { $message = _("You don't have the permission to do that!"); } } @@ -92,17 +90,15 @@ class ServiceGroup public static function edit() { global $user, $message; - if (strlen($_POST['group'])>50) - { + if (strlen($_POST['group']) > 50) { $message = _("Service group name is too long! Character limit is 50"); return; - }else if (strlen(trim($_POST['group']))==0){ + } else if (strlen(trim($_POST['group'])) == 0) { $message = _("Please enter name!"); return; } - if ($user->get_rank()<=1) - { + if ($user->get_rank() <= 1) { global $mysqli; $name = $_POST["group"]; $description = $_POST["description"]; @@ -112,9 +108,8 @@ class ServiceGroup $stmt->bind_param("ssii", $name, $description, $visibility_id, $group_id); $stmt->execute(); $stmt->get_result(); - header("Location: ".WEB_URL."/admin/?do=settings"); - }else - { + header("Location: " . WEB_URL . "/admin/?do=settings"); + } else { $message = _("You don't have the permission to do that!"); } } @@ -125,8 +120,7 @@ class ServiceGroup public static function delete() { global $user, $message; - if ($user->get_rank()<=1) - { + if ($user->get_rank() <= 1) { global $mysqli; $id = $_GET['delete']; @@ -140,10 +134,8 @@ class ServiceGroup $stmt->execute(); $query = $stmt->get_result(); - header("Location: ".WEB_URL."/admin/?do=settings"); - } - else - { + header("Location: " . WEB_URL . "/admin/?do=settings"); + } else { $message = _("You don't have the permission to do that!"); } } @@ -153,7 +145,8 @@ class ServiceGroup * Get list of services groups. * @return array $groups */ - public function get_groups() { + public function get_groups() + { global $mysqli; $stmt = $mysqli->query("SELECT id, name FROM services_groups ORDER by name ASC"); diff --git a/classes/service.php b/classes/service.php index bdb650e..eb014d2 100644 --- a/classes/service.php +++ b/classes/service.php @@ -1,7 +1,8 @@ id = $id; @@ -72,17 +73,15 @@ class Service implements JsonSerializable public static function add() { global $user, $message; - if (strlen($_POST['service'])>50) - { + if (strlen($_POST['service']) > 50) { $message = _("Service name is too long! Character limit is 50"); return; - }else if (strlen(trim($_POST['service']))==0){ + } else if (strlen(trim($_POST['service'])) == 0) { $message = _("Please enter name!"); return; } - if ($user->get_rank()<=1) - { + if ($user->get_rank() <= 1) { global $mysqli; $name = htmlspecialchars($_POST['service']); $description = htmlspecialchars($_POST['description']); @@ -91,48 +90,44 @@ class Service implements JsonSerializable $stmt->bind_param("ssi", $name, $description, $group_id); $stmt->execute(); $stmt->get_result(); - header("Location: ".WEB_URL."/admin/?do=settings"); - }else - { + header("Location: " . WEB_URL . "/admin/?do=settings"); + } else { $message = _("You don't have the permission to do that!"); } } /** - * Processes submitted form and adds service unless problem is encountered, - * calling this is possible only for admin or higher rank. Also checks requirements - * for char limits. - * @return void - */ - public static function edit() - { - global $user, $message; - if (strlen($_POST['service'])>50) - { - $message = _("Service name is too long! Character limit is 50"); - return; - }else if (strlen(trim($_POST['service']))==0){ - $message = _("Please enter name!"); - return; - } - - if ($user->get_rank()<=1) - { - global $mysqli; - $service_id = $_POST["id"]; - $name = htmlspecialchars($_POST['service']); - $description = htmlspecialchars($_POST["description"]); - $group_id = $_POST["group_id"]; - $stmt = $mysqli->prepare("UPDATE services SET name=?, description=?, group_id=? WHERE id = ?"); - $stmt->bind_param("ssii", $name, $description, $group_id, $service_id); - $stmt->execute(); - $stmt->get_result(); - header("Location: ".WEB_URL."/admin/?do=settings"); - }else - { - $message = _("You don't have the permission to do that!"); - } + * Processes submitted form and adds service unless problem is encountered, + * calling this is possible only for admin or higher rank. Also checks requirements + * for char limits. + * @return void + */ + public static function edit() + { + global $user, $message; + if (strlen($_POST['service']) > 50) { + $message = _("Service name is too long! Character limit is 50"); + return; + } else if (strlen(trim($_POST['service'])) == 0) { + $message = _("Please enter name!"); + return; } + if ($user->get_rank() <= 1) { + global $mysqli; + $service_id = $_POST["id"]; + $name = htmlspecialchars($_POST['service']); + $description = htmlspecialchars($_POST["description"]); + $group_id = $_POST["group_id"]; + $stmt = $mysqli->prepare("UPDATE services SET name=?, description=?, group_id=? WHERE id = ?"); + $stmt->bind_param("ssii", $name, $description, $group_id, $service_id); + $stmt->execute(); + $stmt->get_result(); + header("Location: " . WEB_URL . "/admin/?do=settings"); + } else { + $message = _("You don't have the permission to do that!"); + } + } + /** * Deletes this service - first checks if user has permission to do that. * @return void @@ -140,8 +135,7 @@ class Service implements JsonSerializable public static function delete() { global $user, $message; - if ($user->get_rank()<=1) - { + if ($user->get_rank() <= 1) { global $mysqli; $id = $_GET['delete']; @@ -151,8 +145,7 @@ class Service implements JsonSerializable $query = $stmt->get_result(); while ($res = $query->fetch_assoc()) { - if ($res['count']==1) - { + if ($res['count'] == 1) { Incident::delete($res['status']); } } @@ -167,10 +160,8 @@ class Service implements JsonSerializable $stmt->execute(); $query = $stmt->get_result(); - header("Location: ".WEB_URL."/admin/?do=settings"); - } - else - { + header("Location: " . WEB_URL . "/admin/?do=settings"); + } else { $message = _("You don't have the permission to do that!"); } } @@ -180,25 +171,24 @@ class Service implements JsonSerializable * @param Service[] $array array of services * @return void */ - public static function current_status($array){ + public static function current_status($array) + { global $all, $some, $classes; - $statuses = array(0,0,0,0); + $statuses = array(0, 0, 0, 0); $worst = 5; foreach ($array as $service) { - if ($service->status<$worst) - { + if ($service->status < $worst) { $worst = $service->get_status(); } $statuses[$service->get_status()]++; } - echo '
    '; + echo '
    '; - if ($statuses[$worst] == count($array)) - { + if ($statuses[$worst] == count($array)) { echo $all[$worst]; - }else{ + } else { echo $some[$worst]; } echo '
    '; @@ -209,7 +199,8 @@ class Service implements JsonSerializable * @param $boolGroup set to true if the groups name is to be rendered * @return void */ - public function render(){ + public function render() + { global $statuses; global $classes; static $arrCompletedGroups = array(); @@ -218,49 +209,50 @@ class Service implements JsonSerializable // Check if previous ul has been opened, and if a empty/new group is being // render_header, close the UL first. - if ( $boolOpened ) { - if ( empty($this->group_name) || !in_array($this->group_name, $arrCompletedGroups) ) { + if ($boolOpened) { + if (empty($this->group_name) || !in_array($this->group_name, $arrCompletedGroups)) { echo ''; $boolOpened = false; } } // If no group exist or group is new, start a new UL - if ( !empty($this->group_name) && !in_array($this->group_name, $arrCompletedGroups)) { + if (!empty($this->group_name) && !in_array($this->group_name, $arrCompletedGroups)) { echo '
      '; //echo '
        '; // Render the group status if it exists - echo '
      •  ' . $this->group_name .'
        '. _($statuses[$this->status]).'
      • '; + echo '
      •  ' . $this->group_name . '
        ' . _($statuses[$this->status]) . '
      • '; //echo '
      • ' . $this->group_name .'
        status]).'
      • '; $arrCompletedGroups[] = $this->group_name; $boolOpened = true; } - if ( empty($this->group_name)) { + if (empty($this->group_name)) { echo '
          '; -// echo '
            '; + // echo '
              '; $boolFinish = true; } // Render the service status echo '
              '; - echo '
            • ' . $this->name .''; + echo '
            • ' . $this->name . ''; //echo '
            • ' . $this->name . ''; - if(!empty($this->description)) { - echo ' '; + if (!empty($this->description)) { + echo ' '; } - if ($this->status!=-1){?>
              status]);?>
              - status != -1) { ?>
              status]); ?>
              +'; - if ( isset($boolFinish) && $boolFinish) { + if (isset($boolFinish) && $boolFinish) { echo '
            '; } echo '
    '; } - public function jsonSerialize() { + public function jsonSerialize() + { global $statuses; return [ "id" => $this->id, @@ -270,5 +262,4 @@ class Service implements JsonSerializable "status_string" => $statuses[$this->status] ]; } - } diff --git a/classes/subscriber.php b/classes/subscriber.php index 0fef6fd..151e5bd 100644 --- a/classes/subscriber.php +++ b/classes/subscriber.php @@ -4,7 +4,7 @@ * Subscriber class * */ -Class Subscriber +class Subscriber { public $id = null; public $firstname = null; @@ -15,7 +15,8 @@ Class Subscriber public $typeID = null; // Holds subscription type ID - function __construct() { + function __construct() + { $this->firstname = null; $this->lastname = null; $this->userID = ""; @@ -44,7 +45,6 @@ Class Subscriber return $row['token']; } return false; - } public function get_subscriber_by_token($token) { @@ -66,7 +66,7 @@ Class Subscriber { global $mysqli; $stmt = $mysqli->prepare("SELECT subscriberID FROM subscribers WHERE userID LIKE ? AND typeID = ? LIMIT 1"); - $stmt->bind_param("si", $this->userID, $this->typeID ); + $stmt->bind_param("si", $this->userID, $this->typeID); $stmt->execute(); $result = $stmt->get_result(); @@ -77,7 +77,7 @@ Class Subscriber return $row['subscriberID']; } else { // User is not registered in DB, so add if $create = true - if ( $create ) { + if ($create) { $subscriber_id = $this->add($this->typeID, $this->userID, $this->active, $this->firstname, $this->lastname); return $subscriber_id; } @@ -111,7 +111,7 @@ Class Subscriber $expireTime = strtotime("+2 hours"); $updateTime = strtotime("now"); $token = $this->generate_token(); - + $stmt = $mysqli->prepare("INSERT INTO subscribers (typeID, userID, firstname, lastname, token, active, expires, create_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->bind_param("issssiii", $typeID, $userID, $firstname, $lastname, $token, $active, $expireTime, $updateTime); $stmt->execute(); @@ -135,7 +135,6 @@ Class Subscriber $stmt->bind_param("ii", $updateTime, $subscriberID); $stmt->execute(); return true; - } public function activate($subscriberID) @@ -164,7 +163,6 @@ Class Subscriber $stmt->execute(); //$query = $stmt->get_result(); return true; - } public function check_userid_exist() @@ -177,7 +175,7 @@ Class Subscriber $stmt->execute(); $result = $stmt->get_result(); - if($result->num_rows > 0) { + if ($result->num_rows > 0) { $row = $result->fetch_assoc(); $this->id = $row['subscriberID']; $this->populate(); @@ -192,7 +190,7 @@ Class Subscriber $stmt = $mysqli->prepare("SELECT subscriberID, token, userID, active, expires FROM subscribers WHERE token LIKE ? LIMIT 1"); - $stmt->bind_param("s", $token ); + $stmt->bind_param("s", $token); $stmt->execute(); $result = $stmt->get_result(); @@ -205,14 +203,14 @@ Class Subscriber // If account is not already active, check if we are within timeframe of exipre +2h // and active if so, otherwise,delete account and return falsev - if ( $row['active'] <> 1 ) { + if ($row['active'] <> 1) { // Calculate time range for when subscription need to be validated $time_end = $row['expires']; - $time_start = $time_end - (3600*2); // TODO - make this interval configurable via a config option + $time_start = $time_end - (3600 * 2); // TODO - make this interval configurable via a config option $time_now = time(); - if ( ($time_now > $time_start) && ($time_now < $time_end) ) { + if (($time_now > $time_start) && ($time_now < $time_end)) { // Timefram is within range, active user.. $stmt2 = $mysqli->prepare("UPDATE subscribers SET active=1, expires=null WHERE subscriberID = ?"); $stmt2->bind_param("i", $row['subscriberID']); @@ -223,7 +221,6 @@ Class Subscriber $this->userID = $row['userID']; $this->token = $row['token']; return true; - } else { // Timeframe outside of given scope -> delete account $stmt2 = $mysqli->prepare("DELETE FROM subscribers WHERE subscriberID = ?"); @@ -251,7 +248,7 @@ Class Subscriber { global $mysqli; - if ( function_exists('openssl_random_pseudo_bytes') ) { + if (function_exists('openssl_random_pseudo_bytes')) { $token = openssl_random_pseudo_bytes(32); //Generate a random string. $token = bin2hex($token); //Convert the binary data into hexadecimal representation. } else { @@ -265,7 +262,7 @@ Class Subscriber $stmt->bind_param("s", $token); $stmt->execute(); $result = $stmt->get_result(); - if ($result->num_rows > 0 ) { + if ($result->num_rows > 0) { // token already exists, call self again $token = $this->generate_token(); } @@ -285,18 +282,18 @@ Class Subscriber $key = ''; // build range and shuffle range using ASCII table - for ($i=0; $i<=255; $i++) { + for ($i = 0; $i <= 255; $i++) { $range[] = chr($i); } // shuffle our range 3 times - for ($i=0; $i<=3; $i++) { + for ($i = 0; $i <= 3; $i++) { shuffle($range); } // loop for random number generation for ($i = 0; $i < mt_rand($min_length, $max_length); $i++) { - $key .= $range[mt_rand(0, count($range)-1)]; + $key .= $range[mt_rand(0, count($range) - 1)]; } $return = bin2hex($key); @@ -325,5 +322,4 @@ Class Subscriber unset($_SESSION['subscriber_id']); unset($_SESSION['subscriber_token']); } - } diff --git a/classes/subscriptions.php b/classes/subscriptions.php index 43f731f..0eb9f95 100644 --- a/classes/subscriptions.php +++ b/classes/subscriptions.php @@ -4,30 +4,30 @@ * Subscriptions class * */ -Class Subscriptions +class Subscriptions { public function add($userID, $service) { global $mysqli; - + $stmt = $mysqli->prepare("INSERT INTO services_subscriber (subscriberIDFK, serviceIDFK) VALUES (?, ?)"); $stmt->bind_param("ii", $userID, $service); $stmt->execute(); //$query = $stmt->get_result(); return true; } - + public function remove($userID, $service) { global $mysqli; - + $stmt = $mysqli->prepare("DELETE FROM services_subscriber WHERE subscriberIDFK = ? AND serviceIDFK = ?"); $stmt->bind_param("ii", $userID, $service); $stmt->execute(); //$query = $stmt->get_result(); return true; } - + function render_subscribed_services($typeID, $subscriberID, $userID, $token) { global $mysqli; @@ -41,54 +41,54 @@ Class Subscriptions $query = $stmt->get_result(); $strNotifyType = _('E-mail Notification subscription'); - if ( $typeID == 1 ) { $strNotifyType = _('Telegram Notification subscription'); } + if ($typeID == 1) { + $strNotifyType = _('Telegram Notification subscription'); + } - ?> +?>
    - - ' . _("Your subscriptions") . ""; echo '
    '; $subs = array(); // Will be used to hold IDs of services already selected - - if ($query->num_rows){ - while($result = $query->fetch_assoc()) - { - echo ' ' . $result['name'] . ''; + + if ($query->num_rows) { + while ($result = $query->fetch_assoc()) { + echo ' ' . $result['name'] . ''; $subs[] = $result['id']; } - } else { - echo '
    '._("You do not currently subscribe to any services. Please add services from the list below.").'
    '; + echo '
    ' . _("You do not currently subscribe to any services. Please add services from the list below.") . '
    '; } echo "
    "; - + echo '

    ' . _("Add new subscription") . '

    '; // Prepare to query for unselect services. If none are selected, query for all $subsExp = null; - if (count($subs) > 0 ) { - $subsExp = 'NOT IN ('. implode(",", $subs) .')'; + if (count($subs) > 0) { + $subsExp = 'NOT IN (' . implode(",", $subs) . ')'; } $query = $mysqli->query("SELECT services.id, services.name from services WHERE services.id $subsExp"); echo '
    '; - if ($query->num_rows){ - while($result = $query->fetch_assoc()){ - echo ' ' . $result['name'] . ''; + if ($query->num_rows) { + while ($result = $query->fetch_assoc()) { + echo ' ' . $result['name'] . ''; } } else { - echo '
    '._("No further services available for subscriptions.").'
    '; + echo '
    ' . _("No further services available for subscriptions.") . '
    '; } echo '
    '; } - -} \ No newline at end of file +} diff --git a/classes/telegram.php b/classes/telegram.php index 5d506c7..ddaf893 100644 --- a/classes/telegram.php +++ b/classes/telegram.php @@ -1,82 +1,85 @@ $value) { - // $data_check_arr[] = $key . '=' . $value; - $data_check_arr[] = $key . '=' . str_replace('https:/t', 'https://t', $value); - } - sort($data_check_arr); - $data_check_string = implode("\n", $data_check_arr); - $secret_key = hash('sha256', TG_BOT_API_TOKEN, true); - $hash = hash_hmac('sha256', $data_check_string, $secret_key); - if (strcmp($hash, $check_hash) !== 0) { - throw new Exception('Data is NOT from Telegram'); - } - if ((time() - $auth_data['auth_date']) > 86400) { - throw new Exception('Data is outdated'); - } - return $auth_data; + return false; + } + /** + * Check if data is from telegram + * + * This checks if the data provides is from telegram. It includes a Fix for firefox + * + * @param mixed $auth_data The Authentication Data + * + * @return $auth_data + * + */ + function checkTelegramAuthorization($auth_data) + { + $check_hash = $auth_data['hash']; + unset($auth_data['hash']); + $data_check_arr = []; + foreach ($auth_data as $key => $value) { + // $data_check_arr[] = $key . '=' . $value; + $data_check_arr[] = $key . '=' . str_replace('https:/t', 'https://t', $value); } - - - /** - * Save telegram userdata - * - * Save the telegram user data in a cookie - * @return void - */ - function saveTelegramUserData($auth_data) { - $auth_data_json = json_encode($auth_data); - setcookie('tg_user', $auth_data_json); + sort($data_check_arr); + $data_check_string = implode("\n", $data_check_arr); + $secret_key = hash('sha256', TG_BOT_API_TOKEN, true); + $hash = hash_hmac('sha256', $data_check_string, $secret_key); + if (strcmp($hash, $check_hash) !== 0) { + throw new Exception('Data is NOT from Telegram'); } - - function get_telegram_subscriberid($user) - { - global $mysqli; - $stmt = $mysqli->prepare("SELECT subscriberID FROM subscribers WHERE typeID=1 AND userID LIKE ? LIMIT 1"); - $stmt->bind_param("s", $user); - $stmt->execute(); - $result = $stmt->get_result(); - if ( $result->num_rows) { - $row = $result->fetch_assoc(); - $subscriberID = $row['subscriberID']; - return $subscriberID; - } - return null; // Return null on false + if ((time() - $auth_data['auth_date']) > 86400) { + throw new Exception('Data is outdated'); } -} \ No newline at end of file + return $auth_data; + } + + + /** + * Save telegram userdata + * + * Save the telegram user data in a cookie + * @return void + */ + function saveTelegramUserData($auth_data) + { + $auth_data_json = json_encode($auth_data); + setcookie('tg_user', $auth_data_json); + } + + function get_telegram_subscriberid($user) + { + global $mysqli; + $stmt = $mysqli->prepare("SELECT subscriberID FROM subscribers WHERE typeID=1 AND userID LIKE ? LIMIT 1"); + $stmt->bind_param("s", $user); + $stmt->execute(); + $result = $stmt->get_result(); + if ($result->num_rows) { + $row = $result->fetch_assoc(); + $subscriberID = $row['subscriberID']; + return $subscriberID; + } + return null; // Return null on false + } +} diff --git a/classes/token.php b/classes/token.php index 1771367..e1233cb 100644 --- a/classes/token.php +++ b/classes/token.php @@ -1,7 +1,8 @@ prepare("INSERT INTO tokens VALUES(?, ?, ?, ?)"); $stmt->bind_param("siis", $token, $id, $expire, $data); $stmt->execute(); @@ -67,8 +68,8 @@ class Token global $mysqli; $time = time(); $stmt = $mysqli->prepare("DELETE FROM tokens WHERE token = ? OR expirebind_param("sd", $token,$time); + $stmt->bind_param("sd", $token, $time); $stmt->execute(); $stmt->get_result(); } -} \ No newline at end of file +} diff --git a/classes/user.php b/classes/user.php index f613373..a1f3c6d 100644 --- a/classes/user.php +++ b/classes/user.php @@ -1,7 +1,8 @@ execute(); $query = $stmt->get_result(); - if (!$query->num_rows) - { + if (!$query->num_rows) { throw new Exception("User doesn't exist."); return; } @@ -48,7 +48,7 @@ class User { return $this->username; } - + /** * Returns whether this user is active * @return Boolean user active status @@ -57,7 +57,7 @@ class User { return $this->active; } - + /** * Returns rank of this user * @return int rank @@ -66,7 +66,7 @@ class User { return $this->rank; } - + /** * Returns full name of this user * @return String name in "Name Surname" format @@ -86,14 +86,13 @@ class User global $mysqli, $message, $user; $id = $_GET['id']; - if ($this->id!=$_SESSION['user'] && $user->get_rank()<=1 && ($user->get_rank()<$this->rank)) - { + if ($this->id != $_SESSION['user'] && $user->get_rank() <= 1 && ($user->get_rank() < $this->rank)) { $stmt = $mysqli->prepare("UPDATE users SET active = !active WHERE id=?"); $stmt->bind_param("i", $this->id); $stmt->execute(); $stmt->close(); - header("Location: ".WEB_URL."/admin/?do=user&id=".$id); - }else{ + header("Location: " . WEB_URL . "/admin/?do=user&id=" . $id); + } else { $message = _("You don't have the permission to do that!"); } } @@ -108,94 +107,87 @@ class User public static function add() { global $user, $message, $mysqli; - if (INSTALL_OVERRIDE || $user->get_rank()==0) - { - if (strlen(trim($_POST['name']))==0) { + if (INSTALL_OVERRIDE || $user->get_rank() == 0) { + if (strlen(trim($_POST['name'])) == 0) { $messages[] = _("Name"); } - if(strlen(trim($_POST['surname']))==0) { + if (strlen(trim($_POST['surname'])) == 0) { $messages[] = _("Surname"); } - if(strlen(trim($_POST['email']))==0) { + if (strlen(trim($_POST['email'])) == 0) { $messages[] = _("Email"); } - if(strlen(trim($_POST['password']))==0) { + if (strlen(trim($_POST['password'])) == 0) { $messages[] = _("Password"); } - if(!isset($_POST['permission'])) - { + if (!isset($_POST['permission'])) { $messages[] = _("Rank"); } - if (isset($messages)){ - $message = "Please enter ".implode(", ", $messages); + if (isset($messages)) { + $message = "Please enter " . implode(", ", $messages); return; } - + $name = $_POST['name']; $surname = $_POST['surname']; $username = $_POST['username']; $email = $_POST['email']; $pass = $_POST['password']; - - if (!filter_var($email, FILTER_VALIDATE_EMAIL)) - { + + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $message = "Invalid email!"; return; } $variables = array(); - if (strlen($name)>50){ + if (strlen($name) > 50) { $variables[] = 'name: 50'; } - if (strlen($surname)>50){ + if (strlen($surname) > 50) { $variables[] = 'surname: 50'; } - if (strlen($username)>50){ + if (strlen($username) > 50) { $variables[] = 'username: 50'; } - if (strlen($email)>60){ + if (strlen($email) > 60) { $variables[] = 'email: 60'; } - if (!empty($variables)) - { + if (!empty($variables)) { $message = _("Please mind the following character limits: "); $message .= implode(", ", $variables); return; } $salt = uniqid(mt_rand(), true); - $hash = hash('sha256', $pass.$salt); + $hash = hash('sha256', $pass . $salt); $permission = $_POST['permission']; - + $stmt = $mysqli->prepare("INSERT INTO users values (NULL, ?, ?, ?, ?, ?, ?, ?, 1)"); $stmt->bind_param("ssssssi", $email, $username, $name, $surname, $hash, $salt, $permission); $stmt->execute(); - if ($stmt->affected_rows==0) - { + if ($stmt->affected_rows == 0) { $message = _("Username or email already used"); return; } $to = $email; - $subject = _('User account created').' - '.NAME; - $msg = sprintf(_("Hi %s!
    "."Your account has been created. You can login with your email address at %s with password %s - please change it as soon as possible."), $name." ".$surname,WEB_URL."/admin", WEB_URL."/admin", $pass); - $headers = "Content-Type: text/html; charset=utf-8 ".PHP_EOL; - $headers .= "MIME-Version: 1.0 ".PHP_EOL; - $headers .= "From: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; - $headers .= "Reply-To: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; + $subject = _('User account created') . ' - ' . NAME; + $msg = sprintf(_("Hi %s!
    " . "Your account has been created. You can login with your email address at %s with password %s - please change it as soon as possible."), $name . " " . $surname, WEB_URL . "/admin", WEB_URL . "/admin", $pass); + $headers = "Content-Type: text/html; charset=utf-8 " . PHP_EOL; + $headers .= "MIME-Version: 1.0 " . PHP_EOL; + $headers .= "From: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; + $headers .= "Reply-To: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; mail($to, $subject, $msg, $headers); - if (!INSTALL_OVERRIDE) - { - header("Location: ".WEB_URL."/admin/?do=settings"); + if (!INSTALL_OVERRIDE) { + header("Location: " . WEB_URL . "/admin/?do=settings"); } - } - else { + } else { $message = _("You don't have the permission to do that!"); } } @@ -210,13 +202,11 @@ class User public static function login() { global $message, $mysqli; - if (!isset($_POST['email']) && !isset($_POST['email'])) - { + if (!isset($_POST['email']) && !isset($_POST['email'])) { return; } - if ((!isset($_POST['email']) || !isset($_POST['email']))) - { + if ((!isset($_POST['email']) || !isset($_POST['email']))) { $message = _("Please fill in your email and password!"); return; } @@ -228,37 +218,33 @@ class User $stmt->execute(); $query = $stmt->get_result(); - if ($query->num_rows<1) - { + if ($query->num_rows < 1) { $message = _("Wrong email or password"); return; } - + $result = $query->fetch_assoc(); $salt = $result["salt"]; $id = $result["id"]; $active = $result["active"]; - if (!$active) - { + if (!$active) { $message = _("Your account has been disabled. Please contact administrator."); return; } - $hash = hash('sha256', $pass.$salt); + $hash = hash('sha256', $pass . $salt); $stmt = $mysqli->prepare("SELECT count(*) as count FROM users WHERE id=? AND password_hash=?"); $stmt->bind_param("is", $id, $hash); $stmt->execute(); $query = $stmt->get_result(); - if (!$query->fetch_assoc()['count']) - { + if (!$query->fetch_assoc()['count']) { $message = _("Wrong email or password"); return; } - if (isset($_POST['remember'])&&$_POST['remember']) - { + if (isset($_POST['remember']) && $_POST['remember']) { $year = strtotime('+356 days', time()); $token = Token::add($id, 'remember', $year); setcookie('token', $token, $year, "/"); @@ -266,7 +252,7 @@ class User } $_SESSION['user'] = $id; - header("Location: ".WEB_URL."/admin"); + header("Location: " . WEB_URL . "/admin"); } /** @@ -281,24 +267,21 @@ class User $id = $_COOKIE['user']; $token = $_COOKIE['token']; - if (Token::validate($token, $id, "remember")) - { + if (Token::validate($token, $id, "remember")) { $year = strtotime('+356 days', time()); unset($_COOKIE['token']); $_SESSION['user'] = $id; $new_token = Token::add($id, 'remember', $year); setcookie('token', $new_token, $year, "/"); setcookie('user', $id, $year, "/"); - } - else - { + } else { unset($_COOKIE['user']); unset($_COOKIE['token']); setcookie('user', null, -1, '/'); setcookie('token', null, -1, '/'); $message = _("Invalid token detected, please login again!"); } - + Token::delete($token); } /** @@ -308,142 +291,137 @@ class User public function render_user_settings() { global $permissions, $user; - ?> +?>
    -
    <?php echo _(">
    +
    <?php echo _(">
    - id==$_SESSION['user']||$user->get_rank()<1){ - ?> -
    -
    -
    -
    - - -
    -
    - " - title="" class="form-control form-name" - value=name, ENT_QUOTES);?>> - " - title="" class="form-control form-name" - value=surname, ENT_QUOTES);?>> + id == $_SESSION['user'] || $user->get_rank() < 1) { + ?> + +
    +
    +
    + + +
    +
    + " title="" class="form-control form-name" value=name, ENT_QUOTES); ?>> + " title="" class="form-control form-name" value=surname, ENT_QUOTES); ?>> +
    -
    -
    - -
    - +
    + +
    + -

    name." ".$this->surname;?>

    +

    name . " " . $this->surname; ?>

    + } ?>
    -
    +
    -
    +
    id==$_SESSION['user'] || $user->get_rank()<1){?> -
    - - - - -
    - username." "; - if ($user->get_rank()>=1){ - echo ""; - } - } - ?> + if ($this->id == $_SESSION['user'] || $user->get_rank() < 1) { ?> +
    + + + + +
    + username . " "; + if ($user->get_rank() >= 1) { + echo ""; + } + } + ?>
    -
    +
    -
    -
    get_rank() == 0 && $this->id != $_SESSION['user']){?> -
    - - -
    rank];}?>
    -
    -
    - - id==$_SESSION['user']||$user->get_rank()<1) - {?> -
    -
    -
    Email
    -
    -
    - - - - -
    +
    +
    get_rank() == 0 && $this->id != $_SESSION['user']) { ?> +
    + + +
    rank]; + } ?>
    - id == $_SESSION['user'] || $user->get_rank() < 1) { ?> +
    +
    +
    Email
    +
    +
    + + + + +
    +
    +
    +
    + -
    -
    -
    - email; ?> -
    -
    - id==$_SESSION['user']){ - ?> - -
    -
    -
    +
    +
    - - " type="password" class="form-control" name="old_password"> - - " type="password" class="form-control" name="password"> - - " type="password" class="form-control" name="password_repeat"> - + email; ?>
    - id!=$_SESSION['user'] && $user->get_rank()<=1 && ($user->get_rank()<$this->rank)) - {?> -
    -
    -
    - active){ - echo ''._("Deactivate user").""; - }else{ - echo ''._("Activate user").""; - } - ?> + } + + if ($this->id == $_SESSION['user']) { + ?> + +
    +
    +
    +
    + + " type="password" class="form-control" name="old_password"> + + " type="password" class="form-control" name="password"> + + " type="password" class="form-control" name="password_repeat"> + +
    +
    +
    + id != $_SESSION['user'] && $user->get_rank() <= 1 && ($user->get_rank() < $this->rank)) { ?> +
    +
    +
    + active) { + echo '' . _("Deactivate user") . ""; + } else { + echo '' . _("Activate user") . ""; + } + ?> +
    -
    - id; $stmt = $mysqli->prepare("SELECT count(*) FROM users WHERE username LIKE ?"); - $stmt->bind_param("s",$_POST["username"]); + $stmt->bind_param("s", $_POST["username"]); $stmt->execute(); - if ($stmt->num_rows > 0) - { + if ($stmt->num_rows > 0) { $message = _("This username is already taken."); return; } $stmt->close(); - if ($_SESSION['user'] != $id && $user->get_rank()>0) - { + if ($_SESSION['user'] != $id && $user->get_rank() > 0) { $message = _("Cannot change username of other users!"); - }else{ + } else { $stmt = $mysqli->prepare("UPDATE users SET username = ? WHERE id=?"); - $stmt->bind_param("si",$_POST["username"],$id); + $stmt->bind_param("si", $_POST["username"], $id); $stmt->execute(); $stmt->close(); - header("Location: ".WEB_URL."/admin/?do=user&id=".$id); + header("Location: " . WEB_URL . "/admin/?do=user&id=" . $id); } } @@ -484,30 +460,28 @@ class User public function change_name() { global $mysqli, $message, $user; - if (strlen(trim($_POST['name']))==0) { + if (strlen(trim($_POST['name'])) == 0) { $messages[] = _("Name"); } - if(strlen(trim($_POST['surname']))==0) { + if (strlen(trim($_POST['surname'])) == 0) { $messages[] = _("Surname"); } - if (!empty($messages)) - { - $message = "Please enter ".implode(", ", $messages); + if (!empty($messages)) { + $message = "Please enter " . implode(", ", $messages); return; } $id = $this->id; - if ($_SESSION['user'] != $id && $user->get_rank()>0) - { + if ($_SESSION['user'] != $id && $user->get_rank() > 0) { $message = _("Cannot change names of other users!"); - }else{ + } else { $stmt = $mysqli->prepare("UPDATE users SET `name` = ?, `surname` = ? WHERE id=?"); - $stmt->bind_param("ssi",$_POST["name"],$_POST["surname"],$id); + $stmt->bind_param("ssi", $_POST["name"], $_POST["surname"], $id); $stmt->execute(); $stmt->close(); - header("Location: ".WEB_URL."/admin/?do=user&id=".$id); + header("Location: " . WEB_URL . "/admin/?do=user&id=" . $id); } } @@ -521,18 +495,15 @@ class User { global $mysqli, $message; $id = $this->id; - if ($_POST['password']!=$_POST['password_repeat']) - { + if ($_POST['password'] != $_POST['password_repeat']) { $message = _("Passwords do not match!"); return; } - if (!$token) - { - if ($_SESSION['user']!=$id) - { + if (!$token) { + if ($_SESSION['user'] != $id) { $message = _("Cannot change password of other users!"); - }else{ + } else { $stmt = $mysqli->prepare("SELECT password_salt as salt FROM users WHERE id=?"); $stmt->bind_param("i", $id); $stmt->execute(); @@ -541,35 +512,32 @@ class User $salt = $result['salt']; $pass = $_POST['old_password']; - $hash = hash('sha256', $pass.$salt); + $hash = hash('sha256', $pass . $salt); $stmt = $mysqli->prepare("SELECT count(*) as count FROM users WHERE id=? AND password_hash = ?"); $stmt->bind_param("is", $id, $hash); $stmt->execute(); - if ($stmt->get_result()->fetch_assoc()['count']) - { + if ($stmt->get_result()->fetch_assoc()['count']) { $pass = $_POST['password']; - $hash = hash('sha256', $pass.$salt); + $hash = hash('sha256', $pass . $salt); $stmt = $mysqli->prepare("UPDATE users SET password_hash = ? WHERE id=?"); $stmt->bind_param("si", $hash, $id); $stmt->execute(); $stmt->close(); $stmt = $mysqli->prepare("DELETE FROM tokens WHERE user = ? AND data = 'remember'"); - $stmt->bind_param("d", $id); - $stmt->execute(); + $stmt->bind_param("d", $id); + $stmt->execute(); $stmt->get_result(); - + User::logout(); - } - else{ + } else { $message = _("Wrong password!"); } } - }else{ - if (Token::validate($token, $id, "passwd")) - { + } else { + if (Token::validate($token, $id, "passwd")) { $stmt = $mysqli->prepare("SELECT password_salt as salt FROM users WHERE id=?"); $stmt->bind_param("i", $id); $stmt->execute(); @@ -578,20 +546,18 @@ class User $salt = $result['salt']; $pass = $_POST['password']; - $hash = hash('sha256', $pass.$salt); + $hash = hash('sha256', $pass . $salt); $stmt = $mysqli->prepare("UPDATE users SET password_hash = ? WHERE id=?"); - $stmt->bind_param("si", $hash,$id); + $stmt->bind_param("si", $hash, $id); $stmt->execute(); $stmt->close(); $stmt = $mysqli->prepare("DELETE FROM tokens WHERE user = ? AND data = 'remember'"); - $stmt->bind_param("d", $id); - $stmt->execute(); - $stmt->get_result(); - } - else - { + $stmt->bind_param("d", $id); + $stmt->execute(); + $stmt->get_result(); + } else { $message = _("Invalid token detected, please retry your request from start!"); } Token::delete($token); @@ -612,41 +578,41 @@ class User $stmt->execute(); $query = $stmt->get_result(); - $id = $query->fetch_assoc()['id']; + $id = $query->fetch_assoc()['id']; $time = strtotime('+1 day', time()); $token = Token::add($id, 'passwd', $time); - $link = WEB_URL."/admin/?do=lost-password&id=$id&token=$token"; + $link = WEB_URL . "/admin/?do=lost-password&id=$id&token=$token"; $to = $email; $user = new User($id); - $subject = _('Reset password') . ' - '.NAME; - $msg = sprintf(_( "Hi %s!
    Below you will find link to change your password. The link is valid for 24hrs. If you didn't request this, feel free to ignore it.

    RESET PASSWORD

    If the link doesn't work, copy & paste it into your browser:
    %s"), $user->get_name(), $link, $link); - $headers = "Content-Type: text/html; charset=utf-8 ".PHP_EOL; - $headers .= "MIME-Version: 1.0 ".PHP_EOL; - $headers .= "From: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; - $headers .= "Reply-To: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; + $subject = _('Reset password') . ' - ' . NAME; + $msg = sprintf(_("Hi %s!
    Below you will find link to change your password. The link is valid for 24hrs. If you didn't request this, feel free to ignore it.

    RESET PASSWORD

    If the link doesn't work, copy & paste it into your browser:
    %s"), $user->get_name(), $link, $link); + $headers = "Content-Type: text/html; charset=utf-8 " . PHP_EOL; + $headers .= "MIME-Version: 1.0 " . PHP_EOL; + $headers .= "From: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; + $headers .= "Reply-To: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; mail($to, $subject, $msg, $headers); - } + } /** * Sends email with link for email change confirmation (security reasons), link is token protected and valid only once. * @return void */ - public function email_link(){ + public function email_link() + { global $user, $mysqli; - + $email = $_POST['email']; $id = $this->id; - if ($user->get_rank()<1 && $id!=$_SESSION['user']) - { + if ($user->get_rank() < 1 && $id != $_SESSION['user']) { $stmt = $mysqli->prepare("UPDATE users SET email = ? WHERE id=?"); $stmt->bind_param("sd", $email, $id); $stmt->execute(); $stmt->get_result(); - header("Location: ".WEB_URL."/admin/?do=user&id=".$id); + header("Location: " . WEB_URL . "/admin/?do=user&id=" . $id); return; } @@ -654,14 +620,14 @@ class User $token = Token::add($id, 'email;$email', $time); - $link = WEB_URL."/admin/?do=change-email&id=$id&token=$token"; + $link = WEB_URL . "/admin/?do=change-email&id=$id&token=$token"; $to = $email; - $subject = _('Email change').' - '.NAME; - $msg = sprintf(_( "Hi %s!
    Below you will find link to change your email. The link is valid for 24hrs. If you didn't request this, feel free to ignore it.

    CHANGE EMAIL

    If the link doesn't work, copy & paste it into your browser:
    %s"), $user->get_name(), $link, $link); - $headers = "Content-Type: text/html; charset=utf-8 ".PHP_EOL; - $headers .= "MIME-Version: 1.0 ".PHP_EOL; - $headers .= "From: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; - $headers .= "Reply-To: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL; + $subject = _('Email change') . ' - ' . NAME; + $msg = sprintf(_("Hi %s!
    Below you will find link to change your email. The link is valid for 24hrs. If you didn't request this, feel free to ignore it.

    CHANGE EMAIL

    If the link doesn't work, copy & paste it into your browser:
    %s"), $user->get_name(), $link, $link); + $headers = "Content-Type: text/html; charset=utf-8 " . PHP_EOL; + $headers .= "MIME-Version: 1.0 " . PHP_EOL; + $headers .= "From: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; + $headers .= "Reply-To: " . MAILER_NAME . ' <' . MAILER_ADDRESS . '>' . PHP_EOL; mail($to, $subject, $msg, $headers); return _('Confirmation email sent!'); @@ -677,8 +643,7 @@ class User $token = $_GET['token']; $id = $_GET['id']; - if (Token::validate($token, $id, "email;%")) - { + if (Token::validate($token, $id, "email;%")) { $data = explode(";", Token::get_data($token, $id)); $email = $data[1]; @@ -688,25 +653,22 @@ class User $stmt->execute(); $stmt->get_result(); Token::delete($token); - header("Location: ".WEB_URL."/admin/"); - } - else - { + header("Location: " . WEB_URL . "/admin/"); + } else { $message = _("Invalid token detected, please retry your request from start!"); } Token::delete($token); - } /** * Logs current user out. * @return void */ - public static function logout(){ + public static function logout() + { session_unset(); - if (isset($_COOKIE['token'])) - { + if (isset($_COOKIE['token'])) { $token = $_COOKIE['token']; Token::delete($token); unset($_COOKIE['user']); @@ -714,26 +676,25 @@ class User setcookie('user', null, -1, '/'); setcookie('token', null, -1, '/'); } - header("Location: ".WEB_URL."/admin"); + header("Location: " . WEB_URL . "/admin"); } /** * Changes permissions of current user - only super admin can do this, so it checks permission first. * @return void */ - public function change_permission(){ + public function change_permission() + { global $mysqli, $message, $user; - if ($user->get_rank()==0) - { + if ($user->get_rank() == 0) { $permission = $_POST['permission']; $id = $_GET['id']; $stmt = $mysqli->prepare("UPDATE users SET permission=? WHERE id=?"); $stmt->bind_param("si", $permission, $id); - $stmt->execute(); - header("Location: ".WEB_URL."/admin/?do=user&id=".$id); - } - else{ + $stmt->execute(); + header("Location: " . WEB_URL . "/admin/?do=user&id=" . $id); + } else { $message = _("You don't have permission to do that!"); } } -} +} diff --git a/create-server-config.php b/create-server-config.php index c3130da..96a026a 100644 --- a/create-server-config.php +++ b/create-server-config.php @@ -20,4 +20,3 @@ fwrite($f, fread($f2, filesize("IISWebConfig"))); fclose($f); fclose($f2); } -?> diff --git a/css/main.css b/css/main.css index 2909dfe..a825a60 100644 --- a/css/main.css +++ b/css/main.css @@ -183,9 +183,9 @@ a:focus { } article.card input { -background: transparent; -border: none; -border-bottom: 1px white outset; + background: transparent; + border: none; + border-bottom: 1px white outset; } article.card textarea { diff --git a/css/print.css b/css/print.css index d688d07..1971e74 100644 --- a/css/print.css +++ b/css/print.css @@ -1,140 +1,137 @@ @import url(https://fonts.googleapis.com/css?family=Open+Sans:400); @import url(https://fonts.googleapis.com/css?family=Fira+Sans:400,700); -body { - background: #ffffff; - margin: 0; - height: 100%; - line-height: 24px; - font-family: 'Open Sans', sans-serif; +body { + background: #ffffff; + margin: 0; + height: 100%; + line-height: 24px; + font-family: "Open Sans", sans-serif; } -#status-container -{ - border-radius: 0; - border-top: 1px solid #e0e0e0; - border-bottom: 1px solid #e0e0e0; +#status-container { + border-radius: 0; + border-top: 1px solid #e0e0e0; + border-bottom: 1px solid #e0e0e0; } -#status-container .item:last-child -{ - border: none; +#status-container .item:last-child { + border: none; } -#status-container .item{ - border-bottom: 1px solid #e0e0e0; +#status-container .item { + border-bottom: 1px solid #e0e0e0; } -#status-big -{ - float: none; - width: 100%; - text-align: center; - font-family: 'Fira Sans', sans-serif; - font-size: 1.5em +#status-big { + float: none; + width: 100%; + text-align: center; + font-family: "Fira Sans", sans-serif; + font-size: 1.5em; } -#wrapper{ - padding-left: 20%; - padding-right: 20%; +#wrapper { + padding-left: 20%; + padding-right: 20%; } -.service{ - float: left; - box-sizing: border-box; - width:60%; - min-width: 200px; - padding: 15px 35px; - font-weight: bold; - font-size: 1em; - font-family: 'Fira Sans', sans-serif; +.service { + float: left; + box-sizing: border-box; + width: 60%; + min-width: 200px; + padding: 15px 35px; + font-weight: bold; + font-size: 1em; + font-family: "Fira Sans", sans-serif; } -.status{ - float: left; - box-sizing: border-box; - width:40%; - min-width: 150px; - padding: 15px 35px; - text-align: right; - font-size: 0.8em; - font-family: 'Fira Sans', sans-serif; +.status { + float: left; + box-sizing: border-box; + width: 40%; + min-width: 150px; + padding: 15px 35px; + text-align: right; + font-size: 0.8em; + font-family: "Fira Sans", sans-serif; } - -#status-container .status.success{ - color:#2fcc66!important; - font-weight: bolder; +#status-container .status.success { + color: #2fcc66 !important; + font-weight: bolder; } -#status-container .status.warning{ - color:#edaa16!important; - font-weight: bolder; +#status-container .status.warning { + color: #edaa16 !important; + font-weight: bolder; } -#status-container .status.danger{ - color:#e74c3c!important; - font-weight: bolder; +#status-container .status.danger { + color: #e74c3c !important; + font-weight: bolder; } -#status-container .status.primary{ - color:#3A72BD!important; - font-weight: bolder; +#status-container .status.primary { + color: #3a72bd !important; + font-weight: bolder; } -.panel-success{ - border-color:#2fcc66; +.panel-success { + border-color: #2fcc66; } -#footerwrap{ - display: none +#footerwrap { + display: none; } -.btn -{ - display: none +.btn { + display: none; } -h3{ - text-align: center; +h3 { + text-align: center; } -.panel-heading.icon{ - width: 50px; - float: left; - border: none; +.panel-heading.icon { + width: 50px; + float: left; + border: none; } -h2.panel-title{ - float: left; +h2.panel-title { + float: left; } -.panel,.panel-heading,.panel-footer{ - border-width: 3px +.panel, +.panel-heading, +.panel-footer { + border-width: 3px; } body .panel-danger, .panel-danger > .panel-body, .panel-danger > .panel-heading, -.panel-danger > .panel-footer{ - border-color: #a94442 +.panel-danger > .panel-footer { + border-color: #a94442; } body .panel-success, .panel-success > .panel-body, .panel-success > .panel-heading, -.panel-success > .panel-footer{ - border-color: #2fcc66 +.panel-success > .panel-footer { + border-color: #2fcc66; } body .panel-warning, .panel-warning > .panel-body, .panel-warning > .panel-heading, -.panel-warning > .panel-footer{ - border-color: #edaa16 +.panel-warning > .panel-footer { + border-color: #edaa16; } body .panel-primary, .panel-primary > .panel-body, .panel-primary > .panel-heading, -.panel-primary > .panel-footer{ - border-color: #337ab7 -} \ No newline at end of file +.panel-primary > .panel-footer { + border-color: #337ab7; +} diff --git a/email_subscriptions.php b/email_subscriptions.php index 366c2be..a06a29d 100644 --- a/email_subscriptions.php +++ b/email_subscriptions.php @@ -8,11 +8,11 @@ require_once("classes/mailer.php"); //require_once("libs/php_idn/idna.php"); require_once("classes/db-class.php"); $db = new SSDB(); -define("NAME", $db->getSetting($mysqli,"name")); -define("TITLE", $db->getSetting($mysqli,"title")); -define("WEB_URL", $db->getSetting($mysqli,"url")); -define("MAILER_NAME", $db->getSetting($mysqli,"mailer")); -define("MAILER_ADDRESS", $db->getSetting($mysqli,"mailer_email")); +define("NAME", $db->getSetting($mysqli, "name")); +define("TITLE", $db->getSetting($mysqli, "title")); +define("WEB_URL", $db->getSetting($mysqli, "url")); +define("MAILER_NAME", $db->getSetting($mysqli, "mailer")); +define("MAILER_ADDRESS", $db->getSetting($mysqli, "mailer_email")); define("GOOGLE_RECAPTCHA", $db->getBooleanSetting($mysqli, "google_recaptcha")); //define("", $db->getSettings($mysqli, "")); define("GOOGLE_RECAPTCHA_SECRET", $db->getSetting($mysqli, "google_recaptcha_secret")); @@ -37,20 +37,20 @@ $subscription = new Subscriptions(); $boolRegistered = false; -if ( isset($_GET['new']) ) { +if (isset($_GET['new'])) { // Form validation for subscribers signing up $message = ""; - Template :: render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription")); if (isset($_POST['emailaddress'])) { - if (0 == strlen(trim($_POST['emailaddress']))){ + if (0 == strlen(trim($_POST['emailaddress']))) { $messages[] = _("Email address"); } // Perform DNS domain validation on - if ( ! $mailer->verify_domain($_POST['emailaddress']) ) { + if (!$mailer->verify_domain($_POST['emailaddress'])) { $messages[] = _("Domain does not apper to be a valid email domain. (Check MX record)"); } @@ -63,7 +63,7 @@ if ( isset($_GET['new']) ) { 'response' => $_POST["g-recaptcha-response"] ); $options = array( - 'http' => array ( + 'http' => array( 'header' => 'Content-Type: application/x-www-form-urlencoded\r\n', 'method' => 'POST', 'content' => http_build_query($data) @@ -73,19 +73,17 @@ if ( isset($_GET['new']) ) { $verify = file_get_contents($url, false, $context); $captcha_success = json_decode($verify); - if ( $captcha_success->success==false ) { + if ($captcha_success->success == false) { $messages[] = _("reChaptcha validation failed"); } } - if ( isset($messages) ) { + if (isset($messages)) { $message = _("Please check
    "); $message .= implode("
    ", $messages); } - } - if(isset($_POST['emailaddress']) && empty($message)) - { + if (isset($_POST['emailaddress']) && empty($message)) { // Check if email is already registered $boolUserExist = false; @@ -93,23 +91,21 @@ if ( isset($_GET['new']) ) { $subscriber->typeID = 2; // Email $boolUserExist = $subscriber->check_userid_exist(); - $url = WEB_URL."/index.php?do=manage&token=".$subscriber->token; + $url = WEB_URL . "/index.php?do=manage&token=" . $subscriber->token; - if ( ! $boolUserExist ) { + if (!$boolUserExist) { // Create a new subscriber as it does not exist $subscriber->add($subscriber->typeID, $_POST['emailaddress']); - $url = WEB_URL."/index.php?do=manage&token=".$subscriber->token; // Needed again after adding subscriber since token did not exist before add - $msg = sprintf(_("Thank you for registering to receive status updates via email.

    Click on the following link to confirm and manage your subcription: %s. New subscriptions must be confirmed within 2 hours"), $url, NAME .' - ' . _("Validate subscription")); - + $url = WEB_URL . "/index.php?do=manage&token=" . $subscriber->token; // Needed again after adding subscriber since token did not exist before add + $msg = sprintf(_("Thank you for registering to receive status updates via email.

    Click on the following link to confirm and manage your subcription: %s. New subscriptions must be confirmed within 2 hours"), $url, NAME . ' - ' . _("Validate subscription")); } else { - if ( ! $subscriber->active ) { + if (!$subscriber->active) { // Subscriber is registered, but has not been activated yet... - $msg = sprintf(_("Thank you for registering to receive status updates via email.

    Click on the following link to confirm and manage your subcription: %s. New subscriptions must be confirmed within 2 hours"), $url, NAME .' - ' . _("Validate subscription")); + $msg = sprintf(_("Thank you for registering to receive status updates via email.

    Click on the following link to confirm and manage your subcription: %s. New subscriptions must be confirmed within 2 hours"), $url, NAME . ' - ' . _("Validate subscription")); $subscriber->activate($subscriber->id); - } else { // subscriber is registered and active - $msg = sprintf(_("Click on the following link to update your existing subscription: %s"), $url, NAME .' - ' . _("Manage subscription")); + $msg = sprintf(_("Click on the following link to update your existing subscription: %s"), $url, NAME . ' - ' . _("Manage subscription")); $subscriber->update($subscriber->id); } } @@ -119,90 +115,87 @@ if ( isset($_GET['new']) ) { $constellation->render_success($header, $message, true, WEB_URL, _('Go back')); // Send email about new registration - $subject = _('Email subscription registered').' - '.NAME; + $subject = _('Email subscription registered') . ' - ' . NAME; $mailer->send_mail($_POST['emailaddress'], $subject, $msg); $boolRegistered = true; } // Add a new email subscriber - display form - if ( isset($_GET['new']) && (! $boolRegistered) ) { + if (isset($_GET['new']) && (!$boolRegistered)) { if (!empty($message)) { - echo '

    '.$message.'

    '; + echo '

    ' . $message . '

    '; } $strPostedEmail = (isset($_POST['emailaddress'])) ? $_POST['emailaddress'] : ""; - ?> +?> -
    -

    -
    - - -
    - -
    -
    -
    -
    -
    + +

    +
    + +
    -
    - - - Privacy Policy'), POLICY_URL); - echo $msg; - ?> - -
    -
    - - - - +
    +
    +
    +
    +
    +
    +
    + + + Privacy Policy'), POLICY_URL); + echo $msg; + ?> + +
    +
    + + + +typeID = 2; //EMAIL - if ( $subscriber->is_active_subscriber($_GET['token']) ) { + if ($subscriber->is_active_subscriber($_GET['token'])) { // forward user to subscriber list.... $subscriber->set_logged_in(); header('Location: subscriptions.php'); exit; } else { - Template :: render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription")); $header = _("We cannot find a valid subscriber account matching those details"); $message = _("If you have recently subscribed, please make sure you activate the account within two hours of doing so. You are welcome to try and re-subscribe."); $constellation->render_warning($header, $message, true, WEB_URL, _('Go back')); } - - } else if (isset($_GET['do']) && $_GET['do'] == 'unsubscribe') { // Handle unsubscriptions // TODO This function is universal and should probably live elsewhere?? if (isset($_GET['token'])) { $subscriber->typeID = (int) $_GET['type']; - if ( $subscriber->get_subscriber_by_token($_GET['token'])) { + if ($subscriber->get_subscriber_by_token($_GET['token'])) { $subscriber->delete($subscriber->id); $subscriber->set_logged_off(); - Template :: render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription")); $header = _("You have been unsubscribed from our system"); $message = _("We are sorry to see you go. If you want to subscribe again at a later date please feel free to re-subscribe."); - $constellation->render_success($header, $message, true, WEB_URL, _('Go back')); - + $constellation->render_success($header, $message, true, WEB_URL, _('Go back')); } else { // TODO Log token for troubleshooting ? // Cannot find subscriber - show alert - Template :: render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription")); $header = _("We are unable to find any valid subscriber detail matching your submitted data!"); $message = _("If you believe this to be an error, please contact the system admininistrator."); $constellation->render_warning($header, $message, true, WEB_URL, _('Go back')); @@ -216,4 +209,4 @@ if ( isset($_GET['new']) ) { $constellation->render_warning($header, $message, true, WEB_URL, _('Go back')); } } -Template :: render_footer(); +Template::render_footer(); diff --git a/index.php b/index.php index c05380e..18126a1 100644 --- a/index.php +++ b/index.php @@ -1,74 +1,70 @@ getSetting($mysqli,"name")); -define("TITLE", $db->getSetting($mysqli,"title")); -define("WEB_URL", $db->getSetting($mysqli,"url")); -define("MAILER_NAME", $db->getSetting($mysqli,"mailer")); -define("MAILER_ADDRESS", $db->getSetting($mysqli,"mailer_email")); + require_once("config.php"); + require_once("template.php"); + require_once("classes/constellation.php"); + require_once("classes/db-class.php"); + $db = new SSDB(); + define("NAME", $db->getSetting($mysqli, "name")); + define("TITLE", $db->getSetting($mysqli, "title")); + define("WEB_URL", $db->getSetting($mysqli, "url")); + define("MAILER_NAME", $db->getSetting($mysqli, "mailer")); + define("MAILER_ADDRESS", $db->getSetting($mysqli, "mailer_email")); -define("SUBSCRIBE_EMAIL", $db->getBooleanSetting($mysqli,"subscribe_email")); -define("SUBSCRIBE_TELEGRAM", $db->getBooleanSetting($mysqli,"subscribe_telegram")); -define("TG_BOT_USERNAME", $db->getSetting($mysqli,"tg_bot_username")); -define("TG_BOT_API_TOKEN", $db->getSetting($mysqli,"tg_bot_api_token")); -define("GOOGLE_RECAPTCHA", $db->getBooleanSetting($mysqli,"google_recaptcha")); -define("GOOGLE_RECAPTCHA_SITEKEY", $db->getSetting($mysqli,"google_recaptcha_sitekey")); -define("GOOGLE_RECAPTCHA_SECRET", $db->getSetting($mysqli,"google_recaptcha_secret")); -$offset = 0; + define("SUBSCRIBE_EMAIL", $db->getBooleanSetting($mysqli, "subscribe_email")); + define("SUBSCRIBE_TELEGRAM", $db->getBooleanSetting($mysqli, "subscribe_telegram")); + define("TG_BOT_USERNAME", $db->getSetting($mysqli, "tg_bot_username")); + define("TG_BOT_API_TOKEN", $db->getSetting($mysqli, "tg_bot_api_token")); + define("GOOGLE_RECAPTCHA", $db->getBooleanSetting($mysqli, "google_recaptcha")); + define("GOOGLE_RECAPTCHA_SITEKEY", $db->getSetting($mysqli, "google_recaptcha_sitekey")); + define("GOOGLE_RECAPTCHA_SECRET", $db->getSetting($mysqli, "google_recaptcha_secret")); + $offset = 0; -if (isset($_GET['ajax'])) -{ - $constellation->render_incidents(false,$_GET['offset'],5); - exit(); -}else if (isset($_GET['offset'])) -{ - $offset = $_GET['offset']; -} + if (isset($_GET['ajax'])) { + $constellation->render_incidents(false, $_GET['offset'], 5); + exit(); + } else if (isset($_GET['offset'])) { + $offset = $_GET['offset']; + } -if (isset($_GET['subscriber_logout'])){ - setcookie('tg_user', ''); - setcookie('referer', '', time() - 3600); - $_SESSION['subscriber_valid'] = false; - unset($_SESSION['subscriber_userid']); - unset($_SESSION['subscriber_typeid']); - unset($_SESSION['subscriber_id']); - header('Location: index.php'); -} -/* + if (isset($_GET['subscriber_logout'])) { + setcookie('tg_user', ''); + setcookie('referer', '', time() - 3600); + $_SESSION['subscriber_valid'] = false; + unset($_SESSION['subscriber_userid']); + unset($_SESSION['subscriber_typeid']); + unset($_SESSION['subscriber_id']); + header('Location: index.php'); + } + /* $versionfile = fopen("versionfile", "r") or die("Unable to open version file!"); $appversion = fread($versionfile,filesize("versionfile")); fclose($versionfile); @@ -92,30 +88,29 @@ if($db->getSetting($mysqli,"notifyUpdates") == "yes"){ } } */ -Template::render_header("Status"); + Template::render_header("Status"); ?> -
    -

    -
    -
    - render_status();?> -
    +
    +

    +
    +
    + render_status(); ?> +
    -query("SELECT count(*) FROM status")->num_rows) -{ + query("SELECT count(*) FROM status")->num_rows) { ?> -
    -
    -
    -
    - render_incidents(true,$offset); - $constellation->render_incidents(false,$offset); - ?> -
    +
    +
    +
    +
    + render_incidents(true, $offset); + $constellation->render_incidents(false, $offset); + ?>
    +
    negotiate($override); $_SESSION['locale'] = $best_match; - setlocale(LC_ALL, $_SESSION['locale'].".UTF-8"); + setlocale(LC_ALL, $_SESSION['locale'] . ".UTF-8"); bindtextdomain("server-status", __DIR__ . "/locale/"); bind_textdomain_codeset($_SESSION['locale'], "utf-8"); textdomain("server-status"); } -if (isset($_POST['server'])) -{ - $mysqli = new mysqli($_POST['server'],$_POST['dbuser'],$_POST['dbpassword'],$_POST['database']); +if (isset($_POST['server'])) { + $mysqli = new mysqli($_POST['server'], $_POST['dbuser'], $_POST['dbpassword'], $_POST['database']); if ($mysqli->connect_errno) { $message .= sprintf(_("Connection failed: %s\n"), $mysqli->connect_error); } - if (isset($_POST['url']) && filter_var($_POST['url'], FILTER_VALIDATE_URL) === false) - { + if (isset($_POST['url']) && filter_var($_POST['url'], FILTER_VALIDATE_URL) === false) { $message .= _("Please set valid url!"); } //Ostatní má checky existence ve funkci pro pridani - if (0 == strlen(trim($_POST['servername']))){ + if (0 == strlen(trim($_POST['servername']))) { $messages[] = _("Server name"); } - if (0 == strlen(trim($_POST['url']))){ + if (0 == strlen(trim($_POST['url']))) { $messages[] = _("Url"); } - if (0 == strlen(trim($_POST['mailer']))){ + if (0 == strlen(trim($_POST['mailer']))) { $messages[] = _("Mailer name"); } - if (0 == strlen(trim($_POST['title']))){ + if (0 == strlen(trim($_POST['title']))) { $messages[] = _("Title"); } - if (0 == strlen(trim($_POST['mailer_email']))){ + if (0 == strlen(trim($_POST['mailer_email']))) { $messages[] = _("Mailer email"); } - if (0 == strlen(trim($_POST['server']))){ + if (0 == strlen(trim($_POST['server']))) { $messages[] = _("Database server"); } - if (0 == strlen(trim($_POST['database']))){ + if (0 == strlen(trim($_POST['database']))) { $messages[] = _("Database name"); } - if (0 == strlen(trim($_POST['dbuser']))){ + if (0 == strlen(trim($_POST['dbuser']))) { $messages[] = _("Database user"); } - if (0 == strlen(trim($_POST['dbpassword']))) - { + if (0 == strlen(trim($_POST['dbpassword']))) { $messages[] = _("Database password"); } - if (isset($messages)) - { + if (isset($messages)) { $message .= _("Please enter"); $message .= implode(", ", $messages); } } -if(isset($_POST['server']) && empty($message)) -{ +if (isset($_POST['server']) && empty($message)) { define("MAILER_NAME", $_POST['mailer']); define("MAILER_ADDRESS", $_POST['mailer_email']); define("INSTALL_OVERRIDE", true); @@ -102,39 +96,35 @@ if(isset($_POST['server']) && empty($message)) foreach ($array as $value) { $val = trim($value); - if (empty($val)) - { + if (empty($val)) { continue; } $q_res = $mysqli->query($value); - if ($q_res === false) - { + if ($q_res === false) { $message = sprintf(_("Error while creating database. Please check permission for your account or MYSQL version.
    Error: %s"), $mysqli->error); break; } } - if (empty($message)) - { + if (empty($message)) { require_once("classes/constellation.php"); User::add(); } - if (empty($message)) - { + if (empty($message)) { //Create config $config = file_get_contents("config.php.template"); //$config = str_replace("##name##", htmlspecialchars($_POST['servername'], ENT_QUOTES), $config); - $db->setSetting($mysqli,"name",htmlspecialchars($_POST['servername'], ENT_QUOTES)); + $db->setSetting($mysqli, "name", htmlspecialchars($_POST['servername'], ENT_QUOTES)); //$config = str_replace("##title##", htmlspecialchars($_POST['title'], ENT_QUOTES), $config); - $db->setSetting($mysqli,"title",htmlspecialchars($_POST['title'], ENT_QUOTES)); + $db->setSetting($mysqli, "title", htmlspecialchars($_POST['title'], ENT_QUOTES)); //$config = str_replace("##url##", $_POST['url'], $config); - $db->setSetting($mysqli,"url",$_POST['url']); + $db->setSetting($mysqli, "url", $_POST['url']); //$config = str_replace("##mailer##", htmlspecialchars($_POST['mailer'], ENT_QUOTES), $config); - $db->setSetting($mysqli,"mailer",htmlspecialchars($_POST['mailer'], ENT_QUOTES)); + $db->setSetting($mysqli, "mailer", htmlspecialchars($_POST['mailer'], ENT_QUOTES)); //$config = str_replace("##mailer_email##", htmlspecialchars($_POST['mailer_email'], ENT_QUOTES), $config); - $db->setSetting($mysqli,"mailer_email",htmlspecialchars($_POST['mailer_email'], ENT_QUOTES)); + $db->setSetting($mysqli, "mailer_email", htmlspecialchars($_POST['mailer_email'], ENT_QUOTES)); $config = str_replace("##server##", htmlspecialchars($_POST['server'], ENT_QUOTES), $config); $config = str_replace("##database##", htmlspecialchars($_POST['database'], ENT_QUOTES), $config); $config = str_replace("##user##", htmlspecialchars($_POST['dbuser'], ENT_QUOTES), $config); @@ -143,169 +133,174 @@ if(isset($_POST['server']) && empty($message)) $config = str_replace("##policy_name##", htmlspecialchars($_POST['policy_name'], ENT_QUOTES), $config); $config = str_replace("##address##", htmlspecialchars($_POST['address'], ENT_QUOTES), $config); $config = str_replace("##policy_mail##", htmlspecialchars($_POST['policy_mail'], ENT_QUOTES), $config); - $config = str_replace("##policy_phone##", htmlspecialchars($_POST['policy_phone'], ENT_QUOTES),$config); + $config = str_replace("##policy_phone##", htmlspecialchars($_POST['policy_phone'], ENT_QUOTES), $config); $config = str_replace("##who_we_are##", htmlspecialchars($_POST['who_we_are'], ENT_QUOTES), $config); - $policy_url_conf = ( ! empty($_POST['policy_url']) ) ? htmlspecialchars($_POST['policy_url'], ENT_QUOTES) : $_POST['url']."/policy.php"; + $policy_url_conf = (!empty($_POST['policy_url'])) ? htmlspecialchars($_POST['policy_url'], ENT_QUOTES) : $_POST['url'] . "/policy.php"; $config = str_replace("##policy_url##", $policy_url_conf, $config); file_put_contents("config.php", $config); include_once "create-server-config.php"; - $db->setSetting($mysqli,"dbConfigVersion","Version2Beta7"); - $db->setSetting($mysqli,"notifyUpdates","yes"); - $db->setSetting($mysqli,"subscribe_email","no"); - $db->setSetting($mysqli,"subscribe_telegram","no"); - $db->setSetting($mysqli,"tg_bot_api_token",""); - $db->setSetting($mysqli,"tg_bot_username",""); - $db->setSetting($mysqli,"php_mailer","no"); - $db->setSetting($mysqli,"php_mailer_host",""); - $db->setSetting($mysqli,"php_mailer_smtp","no"); - $db->setSetting($mysqli,"php_mailer_path",""); - $db->setSetting($mysqli,"php_mailer_port",""); - $db->setSetting($mysqli,"php_mailer_secure","no"); - $db->setSetting($mysqli,"php_mailer_user",""); - $db->setSetting($mysqli,"php_mailer_pass",""); - $db->setSetting($mysqli,"google_recaptcha","no"); - $db->setSetting($mysqli,"google_recaptcha_secret",""); - $db->setSetting($mysqli,"google_recaptcha_sitekey",""); - $db->setSetting($mysqli,"cron_server_ip",""); - if(!$isDeveleoperEnvironement) { - unlink("create-server-config.php"); - unlink("config.php.template"); - unlink("install.sql"); - unlink(__FILE__); - } - header("Location: ".WEB_URL); + $db->setSetting($mysqli, "dbConfigVersion", "Version2Beta7"); + $db->setSetting($mysqli, "notifyUpdates", "yes"); + $db->setSetting($mysqli, "subscribe_email", "no"); + $db->setSetting($mysqli, "subscribe_telegram", "no"); + $db->setSetting($mysqli, "tg_bot_api_token", ""); + $db->setSetting($mysqli, "tg_bot_username", ""); + $db->setSetting($mysqli, "php_mailer", "no"); + $db->setSetting($mysqli, "php_mailer_host", ""); + $db->setSetting($mysqli, "php_mailer_smtp", "no"); + $db->setSetting($mysqli, "php_mailer_path", ""); + $db->setSetting($mysqli, "php_mailer_port", ""); + $db->setSetting($mysqli, "php_mailer_secure", "no"); + $db->setSetting($mysqli, "php_mailer_user", ""); + $db->setSetting($mysqli, "php_mailer_pass", ""); + $db->setSetting($mysqli, "google_recaptcha", "no"); + $db->setSetting($mysqli, "google_recaptcha_secret", ""); + $db->setSetting($mysqli, "google_recaptcha_sitekey", ""); + $db->setSetting($mysqli, "cron_server_ip", ""); + if (!$isDeveleoperEnvironement) { + unlink("create-server-config.php"); + unlink("config.php.template"); + unlink("install.sql"); + unlink(__FILE__); + } + header("Location: " . WEB_URL); } } Template::render_header(_("Install")); ?> -

    - +

    + MINIMUM_PHP_VERSION - if (strnatcmp(phpversion(), MINIMUM_PHP_VERSION) >= 0) { $preq_phpver = $preq_ok; } +// Check if PHP version if > MINIMUM_PHP_VERSION +if (strnatcmp(phpversion(), MINIMUM_PHP_VERSION) >= 0) { + $preq_phpver = $preq_ok; +} - // Test for mysqlnd precense. The mysqlnd driver provides some extra functions that is not available - // if the plain mysql package is installed, and mysqli_get_client_stats is one of them. This is documented - // on the PHP site at http://www.php.net/manual/en/mysqlnd.stats.php - // This test is also discussed at https://stackoverflow.com/questions/1475701/how-to-know-if-mysqlnd-is-the-active-driver - if ( function_exists('mysqli_get_client_stats') ) { $preq_mysqlnd = $preq_ok; } +// Test for mysqlnd precense. The mysqlnd driver provides some extra functions that is not available +// if the plain mysql package is installed, and mysqli_get_client_stats is one of them. This is documented +// on the PHP site at http://www.php.net/manual/en/mysqlnd.stats.php +// This test is also discussed at https://stackoverflow.com/questions/1475701/how-to-know-if-mysqlnd-is-the-active-driver +if (function_exists('mysqli_get_client_stats')) { + $preq_mysqlnd = $preq_ok; +} - // Check if we have access to write to location - if ( is_writable(__DIR__) ) { $preq_writedir = $preq_ok; } +// Check if we have access to write to location +if (is_writable(__DIR__)) { + $preq_writedir = $preq_ok; +} ?> -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -
    +
    -

    +

    +if (!empty($message)) { +?>

    - - +
    -

    - https://example.com/status - without the trailing slash), so we can mail users link for forgotten password etc...");?> +

    + https://example.com/status - without the trailing slash), so we can mail users link for forgotten password etc..."); ?>
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    - +
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    - +
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -

    - +

    +
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -

    - +

    +
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    " class="form-control">
    +
    " class="form-control" required>
    +
    " class="form-control">
    -
    +
    -
    - - " class="form-control"> +
    + + " class="form-control">
    -

    - +

    +
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    +
    " class="form-control" required>
    -
    " class="form-control" required>
    +
    " class="form-control" required>
    - +
    diff --git a/install.sql b/install.sql index cd3b013..0885546 100644 --- a/install.sql +++ b/install.sql @@ -1,16 +1,16 @@ CREATE TABLE `settings` ( `setting` varchar(255) NOT NULL UNIQUE, `value` varchar(255) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; CREATE TABLE `services` ( `id` int(11) NOT NULL, `name` varchar(50) COLLATE utf8_czech_ci NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; CREATE TABLE `services_status` ( `id` int(11) NOT NULL, `service_id` int(11) NOT NULL, `status_id` int(11) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; CREATE TABLE `status` ( `id` int(11) NOT NULL, `type` int(11) NOT NULL, @@ -19,13 +19,13 @@ CREATE TABLE `status` ( `time` int(11) NOT NULL, `end_time` int(11) NOT NULL, `user_id` int(11) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; CREATE TABLE `tokens` ( `token` varchar(64) COLLATE utf8_czech_ci NOT NULL, `user` int(11) NOT NULL, `expire` int(11) NOT NULL, `data` varchar(80) COLLATE utf8_czech_ci NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; CREATE TABLE `users` ( `id` int(11) NOT NULL, `email` varchar(60) COLLATE utf8_czech_ci NOT NULL, @@ -36,18 +36,18 @@ CREATE TABLE `users` ( `password_salt` char(64) COLLATE utf8_czech_ci NOT NULL, `permission` int(11) NOT NULL DEFAULT '0', `active` tinyint(1) NOT NULL DEFAULT '1' -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; CREATE TABLE `subscribers` ( `subscriberID` int(11) NOT NULL, `telegramID` int(50) NOT NULL, `firstname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `lastname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE `services_subscriber` ( `comboID` int(11) NOT NULL, `subscriberIDFK` int(11) NOT NULL, `serviceIDFK` int(11) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE queue_notify ( id int(11) NOT NULL AUTO_INCREMENT, task_id int(11) NOT NULL, @@ -55,16 +55,14 @@ CREATE TABLE queue_notify ( subscriber_id int(11) NOT NULL, retries tinyint(1) DEFAULT NULL, PRIMARY KEY (id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; - +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; CREATE TABLE services_groups ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL, description varchar(50) DEFAULT NULL, visibility tinyint(4) NOT NULL, PRIMARY KEY (id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; CREATE TABLE queue_task ( id int(11) NOT NULL AUTO_INCREMENT, type_id int(11) NOT NULL, @@ -76,67 +74,79 @@ CREATE TABLE queue_task ( num_errors int(11) DEFAULT NULL, user_id int(11) NOT NULL, PRIMARY KEY (id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; +) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_czech_ci; ALTER TABLE `services` - ADD PRIMARY KEY (`id`); +ADD PRIMARY KEY (`id`); ALTER TABLE `services_status` - ADD PRIMARY KEY (`id`), +ADD PRIMARY KEY (`id`), ADD KEY `service_id` (`service_id`), ADD KEY `status_id` (`status_id`); ALTER TABLE `status` - ADD PRIMARY KEY (`id`), +ADD PRIMARY KEY (`id`), ADD KEY `user_id` (`user_id`); ALTER TABLE `tokens` - ADD PRIMARY KEY (`token`), +ADD PRIMARY KEY (`token`), ADD KEY `user` (`user`); ALTER TABLE `users` - ADD PRIMARY KEY (`id`), +ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `email` (`email`), ADD UNIQUE KEY `username` (`username`); ALTER TABLE `services` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; ALTER TABLE `services_status` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; ALTER TABLE `status` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; ALTER TABLE `users` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; +MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; ALTER TABLE `services_subscriber` - ADD PRIMARY KEY (`comboID`), - ADD UNIQUE KEY `unique_subscription` (`subscriberIDFK`,`serviceIDFK`), +ADD PRIMARY KEY (`comboID`), + ADD UNIQUE KEY `unique_subscription` (`subscriberIDFK`, `serviceIDFK`), ADD KEY `serviceIDFK` (`serviceIDFK`); ALTER TABLE `subscribers` - ADD PRIMARY KEY (`subscriberID`), +ADD PRIMARY KEY (`subscriberID`), ADD UNIQUE KEY `telegramID` (`telegramID`); ALTER TABLE `services_subscriber` - MODIFY `comboID` int(11) NOT NULL AUTO_INCREMENT; +MODIFY `comboID` int(11) NOT NULL AUTO_INCREMENT; ALTER TABLE `subscribers` - MODIFY `subscriberID` int(11) NOT NULL AUTO_INCREMENT; +MODIFY `subscriberID` int(11) NOT NULL AUTO_INCREMENT; ALTER TABLE `services_status` - ADD CONSTRAINT `service_id` FOREIGN KEY (`service_id`) REFERENCES `services` (`id`), +ADD CONSTRAINT `service_id` FOREIGN KEY (`service_id`) REFERENCES `services` (`id`), ADD CONSTRAINT `status_id` FOREIGN KEY (`status_id`) REFERENCES `status` (`id`); ALTER TABLE `status` - ADD CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`); +ADD CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`); ALTER TABLE `tokens` - ADD CONSTRAINT `user` FOREIGN KEY (`user`) REFERENCES `users` (`id`); +ADD CONSTRAINT `user` FOREIGN KEY (`user`) REFERENCES `users` (`id`); ALTER TABLE `services_subscriber` - ADD CONSTRAINT `services_subscriber_ibfk_1` FOREIGN KEY (`subscriberIDFK`) REFERENCES `subscribers` (`subscriberID`) ON DELETE CASCADE ON UPDATE CASCADE, +ADD CONSTRAINT `services_subscriber_ibfk_1` FOREIGN KEY (`subscriberIDFK`) REFERENCES `subscribers` (`subscriberID`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `services_subscriber_ibfk_2` FOREIGN KEY (`serviceIDFK`) REFERENCES `services` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; COMMIT; - -ALTER TABLE `subscribers` CHANGE COLUMN lastname lastname varchar(255) DEFAULT NULL; # was varchar(255) NOT NULL -ALTER TABLE `subscribers` CHANGE COLUMN firstname firstname varchar(255) DEFAULT NULL; # was varchar(255) NOT NULL +ALTER TABLE `subscribers` CHANGE COLUMN lastname lastname varchar(255) DEFAULT NULL; +# was varchar(255) NOT NULL +ALTER TABLE `subscribers` CHANGE COLUMN firstname firstname varchar(255) DEFAULT NULL; +# was varchar(255) NOT NULL ALTER TABLE `subscribers` CHANGE COLUMN telegramID userID varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL; -ALTER TABLE `subscribers` ADD COLUMN typeID tinyint(1) NOT NULL AFTER subscriberID; -ALTER TABLE `subscribers` ADD COLUMN token varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL AFTER lastname; -ALTER TABLE `subscribers` ADD COLUMN expires int(11) DEFAULT NULL; -ALTER TABLE `subscribers` ADD COLUMN active tinyint(1) DEFAULT NULL; -ALTER TABLE `subscribers` ADD COLUMN create_time int(11) DEFAULT NULL; -ALTER TABLE `subscribers` ADD COLUMN update_time int(11) DEFAULT NULL; -ALTER TABLE `subscribers` DROP INDEX telegramID; # was UNIQUE (telegramID) -ALTER TABLE `subscribers` ADD UNIQUE userID (userID); -COMMIT; - -ALTER TABLE services ADD COLUMN description varchar(200) COLLATE utf8_czech_ci NOT NULL; -ALTER TABLE services ADD COLUMN group_id int(11) DEFAULT NULL; +ALTER TABLE `subscribers` +ADD COLUMN typeID tinyint(1) NOT NULL +AFTER subscriberID; +ALTER TABLE `subscribers` +ADD COLUMN token varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL +AFTER lastname; +ALTER TABLE `subscribers` +ADD COLUMN expires int(11) DEFAULT NULL; +ALTER TABLE `subscribers` +ADD COLUMN active tinyint(1) DEFAULT NULL; +ALTER TABLE `subscribers` +ADD COLUMN create_time int(11) DEFAULT NULL; +ALTER TABLE `subscribers` +ADD COLUMN update_time int(11) DEFAULT NULL; +ALTER TABLE `subscribers` DROP INDEX telegramID; +# was UNIQUE (telegramID) +ALTER TABLE `subscribers` +ADD UNIQUE userID (userID); COMMIT; +ALTER TABLE services +ADD COLUMN description varchar(200) COLLATE utf8_czech_ci NOT NULL; +ALTER TABLE services +ADD COLUMN group_id int(11) DEFAULT NULL; +COMMIT; \ No newline at end of file diff --git a/js/admin.js b/js/admin.js index f07ef1a..78e5416 100644 --- a/js/admin.js +++ b/js/admin.js @@ -1,63 +1,65 @@ -(function(){ - $("#time_input").flatpickr({enableTime:true, minDate: "today",time_24hr:true, onChange: function(date, dateStr, instance) { - $("#time_input_js").val(date[0].toISOString()); - }}); - $("#end_time").flatpickr({enableTime:true, minDate: "today",time_24hr:true, onChange: function(date, dateStr, instance) { - $("#end_time_js").val(date[0].toISOString()); // iso date str - }}); +(function () { + $("#time_input").flatpickr({ + enableTime: true, + minDate: "today", + time_24hr: true, + onChange: function (date, dateStr, instance) { + $("#time_input_js").val(date[0].toISOString()); + }, + }); + $("#end_time").flatpickr({ + enableTime: true, + minDate: "today", + time_24hr: true, + onChange: function (date, dateStr, instance) { + $("#end_time_js").val(date[0].toISOString()); // iso date str + }, + }); + var bgcolore = ["bg-danger", "bg-warning", "bg-primary", "bg-success"]; + var bordercolore = ["border-danger", "border-warning", "border-primary", "border-success"]; + var icons = ["fa fa-times", "fa fa-exclamation", "fa fa-info", "fa fa-check"]; - var bgcolore = ["bg-danger", "bg-warning", "bg-primary", "bg-success"]; - var bordercolore = ["border-danger", "border-warning", "border-primary", "border-success"]; - var icons = ["fa fa-times", "fa fa-exclamation", "fa fa-info", "fa fa-check"]; + $("body").on("change", "#new-incident select", function () { + var val = parseInt($(this).val()); //this should make exploitation harder - $("body").on("change","#new-incident select", function(){ - var val = parseInt($(this).val()); //this should make exploitation harder + $("#new-incident .card.new .card-colore i").get(0).className = icons[val]; + $("#new-incident .card.new .icon").get(0).className = "card-colore icon " + bgcolore[val]; + $("#new-incident .card.new").get(0).className = "card " + bordercolore[val] + " new"; + $("#new-incident .card.new .card-header").get(0).className = "card-colore card-header " + bgcolore[val] + " " + bordercolore[val]; + $("#time_input").val(""); + $("#end_time").val(""); + }); - $("#new-incident .card.new .card-colore i").get(0).className = icons[val]; - $("#new-incident .card.new .icon").get(0).className = "card-colore icon " + bgcolore[val]; - $("#new-incident .card.new").get(0).className = "card " + bordercolore[val] + " new"; - $("#new-incident .card.new .card-header").get(0).className = "card-colore card-header " + bgcolore[val] + " " + bordercolore[val] ; - $("#time_input").val(""); - $("#end_time").val(""); - }); + $("#new-incident select").trigger("change"); - $("#new-incident select").trigger("change"); + $("body").on("submit", "#new-incident", function () { + var time = Date.parse($("#time_input").val()); + var end_time = Date.parse($("#end_time").val()); + var type = $("#type").val() || 0; - $("body").on("submit","#new-incident",function(){ - var time = Date.parse($("#time_input").val()); - var end_time = Date.parse($("#end_time").val()); - var type = $("#type").val() || 0; + if (parseInt(type) === 2 && (isNaN(time) || isNaN(end_time))) { + if (isNaN(end_time)) { + $("#time_input").addClass("error"); + $.growl.error({ message: "Start time is invalid!" }); + } - if (parseInt(type) === 2 &&(isNaN(time) || isNaN(end_time))) - { - if (isNaN(end_time)) - { - $("#time_input").addClass("error"); - $.growl.error({ message: "Start time is invalid!" }); - } - - if (isNaN(end_time)) - { - $("#end_time").addClass("error"); - $.growl.error({ message: "End time is invalid!" }); - } - return false; - } - else if (parseInt(type) === 2 && time >= end_time) - { - $.growl.error({ message: "End time is either the same or earlier than start time!" }); - $("#time").addClass("error"); - $("#end_time").addClass("error"); - return false; - } + if (isNaN(end_time)) { + $("#end_time").addClass("error"); + $.growl.error({ message: "End time is invalid!" }); + } + return false; + } else if (parseInt(type) === 2 && time >= end_time) { + $.growl.error({ message: "End time is either the same or earlier than start time!" }); + $("#time").addClass("error"); + $("#end_time").addClass("error"); + return false; + } - if($("#status-container :checkbox:checked").length === 0) - { - $.growl.error({ message: "Please check at least one service!" }); - $("#status-container").addClass("error"); - return false; - } - }); + if ($("#status-container :checkbox:checked").length === 0) { + $.growl.error({ message: "Please check at least one service!" }); + $("#status-container").addClass("error"); + return false; + } + }); })(); - diff --git a/js/main.js b/js/main.js index 063b261..68f4a70 100644 --- a/js/main.js +++ b/js/main.js @@ -1,32 +1,29 @@ -function timeago() -{ - $("time.timeago").timeago(); - $("time.timeago").each(function(){ - var date = new Date($(this).attr("datetime")); - $(this).attr("title",date.toLocaleString()); - }); +function timeago() { + $("time.timeago").timeago(); + $("time.timeago").each(function () { + var date = new Date($(this).attr("datetime")); + $(this).attr("title", date.toLocaleString()); + }); } -(function(){ - jQuery.timeago.settings.allowFuture = true; +(function () { + jQuery.timeago.settings.allowFuture = true; - timeago(); - - $("body").on("click", ".navbar-toggle", function(){ - $($(this).data("target")).toggleClass("collapse"); - }); - - var incidents = $('.timeline'); - $("body").on("click", "#loadmore", function(e){ - e.preventDefault(); - var url = $("#loadmore").attr("href") + "&ajax=true"; - $("#loadmore").remove(); - - $.get(url, - function(data){ - incidents.append(data); - timeago(); - }); - }); - })(); - + timeago(); + + $("body").on("click", ".navbar-toggle", function () { + $($(this).data("target")).toggleClass("collapse"); + }); + + var incidents = $(".timeline"); + $("body").on("click", "#loadmore", function (e) { + e.preventDefault(); + var url = $("#loadmore").attr("href") + "&ajax=true"; + $("#loadmore").remove(); + + $.get(url, function (data) { + incidents.append(data); + timeago(); + }); + }); +})(); diff --git a/policy.php b/policy.php index 9379583..43dfd01 100644 --- a/policy.php +++ b/policy.php @@ -1,48 +1,48 @@ " . _("Privacy Policy") . ""; - echo "

    " . _("Who we are") . "

    "; - echo WHO_WE_ARE; - echo "

    " . _("Contact") . "

    "; - echo POLICY_NAME . "
    "; - echo ADDRESS . "
    "; - echo POLICY_MAIL . "
    "; - if(defined('POLICY_PHONE') && POLICY_PHONE != ""){ - echo POLICY_PHONE . "
    "; - } +echo "

    " . _("Privacy Policy") . "

    "; +echo "

    " . _("Who we are") . "

    "; +echo WHO_WE_ARE; +echo "

    " . _("Contact") . "

    "; +echo POLICY_NAME . "
    "; +echo ADDRESS . "
    "; +echo POLICY_MAIL . "
    "; +if (defined('POLICY_PHONE') && POLICY_PHONE != "") { + echo POLICY_PHONE . "
    "; +} - echo '

    ' . _("What personal data we collect and why") . '

    '; - echo '

    ' . _("General") . "

    "; - echo _("If you access our websites, the following information will be saved: IP-address, Date, Time, Browser queries, +echo '

    ' . _("What personal data we collect and why") . '

    '; +echo '

    ' . _("General") . "

    "; +echo _("If you access our websites, the following information will be saved: IP-address, Date, Time, Browser queries, General information about your browser, operating system and all search queries on the sites. This user data will be used for anonym user statistics to recognize trends and improve our content. ") . "
    "; - echo '

    ' . _("Telegram") . "

    "; - echo _("If you use the Telegram Login Widget (The blue \"Login with Telegram\" button), we recive the following data from the service \"Telegram\" (telegram.org):"); - echo '
      +echo '

      ' . _("Telegram") . "

      "; +echo _("If you use the Telegram Login Widget (The blue \"Login with Telegram\" button), we recive the following data from the service \"Telegram\" (telegram.org):"); +echo '
      • ' . _("Your Telegram-User-ID") . "
      • " . _("Your Telegram username") . '
      • ' . _("The name you provided when registering with Telegram.") . '
      • ' . _("Your telegram profile picture") . '
      '; - echo _("Although we are receiving this data, we only save your telegram ID, your telegram username and the first and last name you provided telegram when registred for their service."); - echo _("We are saving this data, to provide a subscription service which alerts you about status update via our telegram bot. With this data we know who we need to send the alert to. Also we know your name, so we can say hi to you."); - echo _("Because of this, we also save who has subscribed which service."); - echo "

      " . _("How we protect your data") . "

      "; - echo _("In collaboration with our hosting provider we try our best to protect our +echo _("Although we are receiving this data, we only save your telegram ID, your telegram username and the first and last name you provided telegram when registred for their service."); +echo _("We are saving this data, to provide a subscription service which alerts you about status update via our telegram bot. With this data we know who we need to send the alert to. Also we know your name, so we can say hi to you."); +echo _("Because of this, we also save who has subscribed which service."); +echo "

      " . _("How we protect your data") . "

      "; +echo _("In collaboration with our hosting provider we try our best to protect our databases against access from third parties, losses, misuse or forgery. ") . "

      "; - echo "

      " . _("Third party that receive your personal data") . "

      "; - echo "Our hosting provider can access the date we store on their server. We have a data processing agreement with them."; - echo "

      " . _("Cookies") . "

      "; - echo _("This site uses cookies – small text files that are placed on your machine to help the site provide a better user experience. +echo "

      " . _("Third party that receive your personal data") . "

      "; +echo "Our hosting provider can access the date we store on their server. We have a data processing agreement with them."; +echo "

      " . _("Cookies") . "

      "; +echo _("This site uses cookies – small text files that are placed on your machine to help the site provide a better user experience. In general, cookies are used to retain user preferences, store information for things like shopping carts, and provide anonymised tracking data to third party applications like Google Analytics. As a rule, cookies will make your browsing experience better. However, you may prefer to disable cookies on this site and on others. The most effective way to do this is to disable cookies in your browser. We suggest consulting the Help section of your browser or taking a look at the About Cookies website which offers guidance for all modern browsers"); - Template::render_footer(); +Template::render_footer(); diff --git a/subscriptions.php b/subscriptions.php index ad9435b..fea6dbf 100644 --- a/subscriptions.php +++ b/subscriptions.php @@ -6,11 +6,11 @@ require_once("classes/subscriptions.php"); require_once("classes/telegram.php"); require_once("classes/db-class.php"); $db = new SSDB(); -define("NAME", $db->getSetting($mysqli,"name")); -define("TITLE", $db->getSetting($mysqli,"title")); -define("WEB_URL", $db->getSetting($mysqli,"url")); -define("MAILER_NAME", $db->getSetting($mysqli,"mailer")); -define("MAILER_ADDRESS", $db->getSetting($mysqli,"mailer_email")); +define("NAME", $db->getSetting($mysqli, "name")); +define("TITLE", $db->getSetting($mysqli, "title")); +define("WEB_URL", $db->getSetting($mysqli, "url")); +define("MAILER_NAME", $db->getSetting($mysqli, "mailer")); +define("MAILER_ADDRESS", $db->getSetting($mysqli, "mailer_email")); define("SUBSCRIBE_EMAIL", $db->getBooleanSetting($mysqli, "subscribe_email")); define("SUBSCRIBE_TELEGRAM", $db->getBooleanSetting($mysqli, "subscribe_telegram")); define("GOOGLE_RECAPTCHA", $db->getSetting($mysqli, "google_recaptcha")); @@ -24,34 +24,33 @@ $telegram = new Telegram(); Template::render_header("Subscriptions"); -if ( SUBSCRIBE_TELEGRAM && $_SESSION['subscriber_typeid'] == 2 ) { +if (SUBSCRIBE_TELEGRAM && $_SESSION['subscriber_typeid'] == 2) { $tg_user = $telegram->getTelegramUserData(); // TODO: Do we need this any longer? } -if( $_SESSION['subscriber_valid'] ){ +if ($_SESSION['subscriber_valid']) { $typeID = $_SESSION['subscriber_typeid']; $subscriberID = $_SESSION['subscriber_id']; $userID = $_SESSION['subscriber_userid']; $token = $_SESSION['subscriber_token']; - if(isset($_GET['add'])){ + if (isset($_GET['add'])) { $subscription->add($subscriberID, $_GET['add']); } - if(isset($_GET['remove'])){ + if (isset($_GET['remove'])) { $subscription->remove($subscriberID, $_GET['remove']); } $subscription->render_subscribed_services($typeID, $subscriberID, $userID, $token); - } else { $header = _("Your session has expired or you tried something we don't suppprt"); $message = _('If your session expired, retry your link or in case of Telegram use the login button in the top menu.'); $constellation->render_warning($header, $message); - header('Location: index.php'); + header('Location: index.php'); } Template::render_footer(); diff --git a/telegram_check.php b/telegram_check.php index 595670f..0602a70 100644 --- a/telegram_check.php +++ b/telegram_check.php @@ -1,15 +1,14 @@ getSetting($mysqli,"name")); -define("TITLE", $db->getSetting($mysqli,"title")); -define("WEB_URL", $db->getSetting($mysqli,"url")); -define("MAILER_NAME", $db->getSetting($mysqli,"mailer")); -define("MAILER_ADDRESS", $db->getSetting($mysqli,"mailer_email")); -define("SUBSCRIBE_TELEGRAM", $db->getBooleanSetting($mysqli, "subscribe_telegram")); +define("NAME", $db->getSetting($mysqli, "name")); +define("TITLE", $db->getSetting($mysqli, "title")); +define("WEB_URL", $db->getSetting($mysqli, "url")); +define("MAILER_NAME", $db->getSetting($mysqli, "mailer")); +define("MAILER_ADDRESS", $db->getSetting($mysqli, "mailer_email")); define("SUBSCRIBE_TELEGRAM", $db->getBooleanSetting($mysqli, "subscribe_telegram")); define("TG_BOT_API_TOKEN", $db->getSetting($mysqli, "tg_bot_api_token")); define("TG_BOT_USERNAME", $db->getSetting($mysqli, "tg_bot_username")); diff --git a/template.php b/template.php index 715c100..09706cf 100644 --- a/template.php +++ b/template.php @@ -1,224 +1,241 @@ '; - // If subscriber is not logged on, display subscriber menus - if ( (!isset($_SESSION['subscriber_valid'])) || false == $_SESSION['subscriber_valid'] ) { - $strSubsMenu .= '
    •  ' . _('Subscribe via email') . '
    • '; + } + if ($SUBSCRIBE_TELEGRAM) { + $strSubsMenu .= '
    • '; + } + $strSubsMenu .= '
    '; + } + } + // If subscriber is logged on, display unsub and logoff menu points + if ((isset($_SESSION['subscriber_valid'])) && $_SESSION['subscriber_valid']) { + $strSubsMenu .= '
  • ' . _('Subscriptions') . '
  • '; + $strSubsMenu .= '
  • ' . _('Logout') . '
  • '; + } + $strSubsMenu .= ''; + } + } +?> + + + + + + <?php echo $page_name . " - " . NAME ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - <?php echo $page_name." - ".NAME ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
    + -
    + if (!$admin) { + ?> +
    + - + /** + * Renders a toggle switch + * Created by Yigit Kerem Oktay + * @param String $toggletext will decide what the description text next to the toggle will be + * @param String $input_name will decide what the HTML Name attribute of the toggle will be + * @param Boolean $checked will decide if the toggle will initially be on or off + */ + public static function render_toggle($toggletext, $input_name, $checked) + { + ?>
    -

    -
    - get_accepted_langs(); - ?> -
    -
    -
    -
    -
    Copyright © Server Status Project Contributors 1){ echo " and ".COPYRIGHT_TEXT; } ?>
    -
    -
    - - - + get_accepted_langs(); + ?> +
    +
    +
    +
    +
    Copyright © Server Status Project Contributors 1) { + echo " and " . COPYRIGHT_TEXT; + } ?>
    +
    +
    + + + +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    - - - - - - - - - - - - - + + + + + + + + + + + + + + Date: Thu, 18 Mar 2021 22:06:04 +0100 Subject: [PATCH 11/47] html tags and container class --- template.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/template.php b/template.php index 09706cf..180eee8 100644 --- a/template.php +++ b/template.php @@ -102,8 +102,8 @@ class Template -
    - + + -
    +
    -
    +
    @@ -190,8 +190,8 @@ class Template global $negotiator; $lang_names = $negotiator->get_accepted_langs(); ?> -
    -
    +
    + From 19c35b59c650d09fe3c5ce177daf633907fe0847 Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 22:06:21 +0100 Subject: [PATCH 12/47] redesign login form --- admin/login-form.php | 36 +++++++++++++++++++++++------------- css/main.css | 1 - 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/admin/login-form.php b/admin/login-form.php index 0521f93..c412114 100644 --- a/admin/login-form.php +++ b/admin/login-form.php @@ -11,20 +11,30 @@ Template::render_header(_("Login"));

    -
    - - " class="form-control" name="email" id="email" type="email" tabindex="1" value="" required> -
    -
    - - " class="form-control" name="pass" id="pass" type="password" tabindex="2" required> -
    - - +
    +
    +

    +
    +
    +
    + + " value="" required> +
    +
    + + " required> +
    + +
    +
    + +
    + +
    +
    + " class="btn btn-success float-end"> +
    -
    -
    -
    diff --git a/css/main.css b/css/main.css index a825a60..457ec0c 100644 --- a/css/main.css +++ b/css/main.css @@ -156,7 +156,6 @@ a:focus { } #login-form { - max-width: 500px; padding-top: 20px; } From 12531401a5d55a2c7afc78e3e52a5cebb787471d Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 22:14:15 +0100 Subject: [PATCH 13/47] icons centered on settings page --- admin/settings.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/admin/settings.php b/admin/settings.php index 309b32f..45a09dc 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -51,7 +51,7 @@ if (isset($message)) { echo "" . $result['group_name'] . ""; if ($user->get_rank() <= 1) { - echo ''; + echo ''; } echo ""; } ?> @@ -80,7 +80,7 @@ if (isset($message)) { get_rank() <= 1) { ?> - + @@ -96,7 +96,7 @@ if (isset($message)) { echo "" . $visibility[$result['visibility']] . ""; if ($user->get_rank() <= 1) { - echo ''; + echo ''; } echo ""; } ?> @@ -120,7 +120,7 @@ if (isset($message)) { - Active + Active @@ -133,9 +133,8 @@ if (isset($message)) { echo "" . $result['name'] . ""; echo "" . $result['surname'] . ""; echo "" . $result['email'] . ""; - echo "" . $permissions[$result['permission']] . ""; - echo ""; - echo ""; + echo "" . $permissions[$result['permission']] . ""; + echo ""; echo ""; } ?> From 82c9ecbaad6c37ee12920f1cbfed0f463b94a5e1 Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 23:20:41 +0100 Subject: [PATCH 14/47] cleanup, classes lifted to bootstrap 5 --- admin/dashboard.php | 12 +-- admin/lost-password.php | 6 +- admin/new-user.php | 2 +- admin/options.php | 2 +- admin/service-group.php | 2 +- admin/service.php | 2 +- admin/settings.php | 184 +++++++++++++++++++++------------------- classes/incident.php | 8 +- classes/user.php | 20 ++--- css/main.css | 10 ++- install.php | 2 +- 11 files changed, 136 insertions(+), 114 deletions(-) diff --git a/admin/dashboard.php b/admin/dashboard.php index 5272f8a..a9a2297 100644 --- a/admin/dashboard.php +++ b/admin/dashboard.php @@ -36,13 +36,13 @@ Template::render_header(_("Dashboard"), true);

    -
    +

    -
    +
    " value="" required> - "> - + "> +
    @@ -83,8 +83,8 @@ Template::render_header(_("Dashboard"), true); diff --git a/admin/lost-password.php b/admin/lost-password.php index f919933..c9cfe2a 100644 --- a/admin/lost-password.php +++ b/admin/lost-password.php @@ -38,10 +38,10 @@ Template::render_header(_("Lost password")); -
    +
    " type="email" required> - +
    " type="password" class="form-control" name="password"> " type="password" class="form-control" name="password_repeat"> - + diff --git a/admin/new-user.php b/admin/new-user.php index 92b95b0..54ce434 100644 --- a/admin/new-user.php +++ b/admin/new-user.php @@ -43,5 +43,5 @@ Template::render_header(_("New user"), true); ?>
    - + \ No newline at end of file diff --git a/admin/options.php b/admin/options.php index ac7ed0f..c557e8b 100644 --- a/admin/options.php +++ b/admin/options.php @@ -182,5 +182,5 @@ Template::render_header(_("Options"), true); - + \ No newline at end of file diff --git a/admin/service-group.php b/admin/service-group.php index 6bc4261..655fb42 100644 --- a/admin/service-group.php +++ b/admin/service-group.php @@ -84,5 +84,5 @@ if (!$boolEdit) { echo ''; } ?> - + \ No newline at end of file diff --git a/admin/service.php b/admin/service.php index 0a7a543..8c07488 100644 --- a/admin/service.php +++ b/admin/service.php @@ -85,5 +85,5 @@ if (!$boolEdit) { echo ''; } ?> - + \ No newline at end of file diff --git a/admin/settings.php b/admin/settings.php index 45a09dc..4f2d7e8 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -18,17 +18,19 @@ if (isset($message)) {

    -

    - get_rank() <= 1) { ?> -
    -
    - -
    -
    - -
    +
    +
    + get_rank() <= 1) { ?> + + +
    +
    +

    +
    +
    +
    +
    - @@ -51,7 +53,7 @@ if (isset($message)) { echo ""; if ($user->get_rank() <= 1) { - echo ''; + echo ''; } echo ""; } ?> @@ -61,83 +63,95 @@ if (isset($message)) {
    -

    - get_rank() <= 1) { ?> -
    -
    - -
    - - -
    -
    " . $result['group_name'] . "
    - - - - - - - - - get_rank() <= 1) { ?> - - - - - - query("SELECT sg.* , (SELECT COUNT(*) FROM services WHERE services.group_id = sg.id) AS counter FROM services_groups AS sg ORDER BY sg.id ASC"); - while ($result = $query->fetch_assoc()) { - echo ""; - //echo ""; - echo '"; - echo ""; - - if ($user->get_rank() <= 1) { - echo ''; - } - echo ""; - } ?> - -
    ".$result['id']."' . $result['name'] . ''; - echo ' ' . $result['counter'] . ''; - echo "" . $result['description'] . "" . $visibility[$result['visibility']] . "
    +
    +
    + get_rank() <= 1) { ?> + + +
    +
    +

    +
    +
    +
    +
    + + + + + + + + + + get_rank() <= 1) { ?> + + + + + + query("SELECT sg.* , (SELECT COUNT(*) FROM services WHERE services.group_id = sg.id) AS counter FROM services_groups AS sg ORDER BY sg.id ASC"); + while ($result = $query->fetch_assoc()) { + echo ""; + //echo ""; + echo '"; + echo ""; + + if ($user->get_rank() <= 1) { + echo ''; + } + echo ""; + } ?> + +
    ".$result['id']."' . $result['name'] . ''; + echo ' ' . $result['counter'] . ''; + echo "" . $result['description'] . "" . $visibility[$result['visibility']] . "
    +
    -
    -

    - get_rank() == 0) { ?> -
    - - - - - - - - - - - - - - - query("SELECT * FROM users"); - while ($result = $query->fetch_assoc()) { - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - } ?> - -
    Active
    " . $result['id'] . "" . $result['username'] . "" . $result['name'] . "" . $result['surname'] . "" . $result['email'] . "" . $permissions[$result['permission']] . "
    +
    +
    + get_rank() == 0) { ?> + + +
    +
    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + query("SELECT * FROM users"); + while ($result = $query->fetch_assoc()) { + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } ?> + +
    Active
    " . $result['id'] . "" . $result['username'] . "" . $result['name'] . "" . $result['surname'] . "" . $result['email'] . "" . $permissions[$result['permission']] . "
    +
    \ No newline at end of file diff --git a/classes/incident.php b/classes/incident.php index 503d827..5cbd00e 100644 --- a/classes/incident.php +++ b/classes/incident.php @@ -186,12 +186,12 @@ class Incident implements JsonSerializable
    title; ?> -
    id . '" class="pull-right delete">'; + echo ''; } ?>
    +
    setBreaksEnabled(true)->text($this->text); ?> @@ -199,10 +199,10 @@ class Incident implements JsonSerializable diff --git a/classes/user.php b/classes/user.php index a1f3c6d..56b6fb2 100644 --- a/classes/user.php +++ b/classes/user.php @@ -311,7 +311,7 @@ class User
    - +
    - +
    username . " "; - if ($user->get_rank() >= 1) { - echo ""; - } - } - ?> + if ($user->get_rank() >= 1) { + echo ""; + } + } + ?>
    @@ -354,7 +354,7 @@ class User echo ""; } ?> - +
    rank]; @@ -371,7 +371,7 @@ class User
    - +
    @@ -401,7 +401,7 @@ class User " type="password" class="form-control" name="password"> " type="password" class="form-control" name="password_repeat"> - +
    diff --git a/css/main.css b/css/main.css index 457ec0c..8d34669 100644 --- a/css/main.css +++ b/css/main.css @@ -222,7 +222,7 @@ article.card textarea { } .new-service { - width: 40%; + width: 100%; min-width: 250px; } @@ -285,6 +285,14 @@ body h3 { margin-top: 18px; } +.settings-header { + padding-top: 20px; +} + +.settings-header .float-start h3 { + margin: 0; +} + .row.user .input-group { width: 100%; margin-bottom: 5px; diff --git a/install.php b/install.php index 81c37cc..55a177a 100644 --- a/install.php +++ b/install.php @@ -300,7 +300,7 @@ if (!empty($message)) {
    " class="form-control" required>
    - +
    From c08f194642d6b5704122773a24ad807a8651c2e4 Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 18 Mar 2021 23:21:39 +0100 Subject: [PATCH 15/47] Button colored --- admin/dashboard.php | 2 +- js/admin.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/admin/dashboard.php b/admin/dashboard.php index a9a2297..7ef9059 100644 --- a/admin/dashboard.php +++ b/admin/dashboard.php @@ -102,7 +102,7 @@ Template::render_header(_("Dashboard"), true); } ?> - +
    Date: Thu, 18 Mar 2021 23:30:12 +0100 Subject: [PATCH 16/47] fix button position --- classes/user.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/classes/user.php b/classes/user.php index 56b6fb2..1eaa7a6 100644 --- a/classes/user.php +++ b/classes/user.php @@ -310,9 +310,7 @@ class User
    -
    - -
    + Date: Fri, 19 Mar 2021 00:23:51 +0100 Subject: [PATCH 17/47] remove border --- admin/dashboard.php | 2 +- css/main.css | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/admin/dashboard.php b/admin/dashboard.php index 7ef9059..f2f0100 100644 --- a/admin/dashboard.php +++ b/admin/dashboard.php @@ -37,7 +37,7 @@ Template::render_header(_("Dashboard"), true);

    -
    +

    Date: Fri, 19 Mar 2021 08:53:24 +0100 Subject: [PATCH 18/47] move vendor folder to root add flatpickr locally, update to jquerry 3.6 --- template.php | 16 ++++++---------- .../bootstrap/css}/bootstrap-grid.css | 0 .../bootstrap/css}/bootstrap-grid.css.map | 0 .../bootstrap/css}/bootstrap-grid.min.css | 0 .../bootstrap/css}/bootstrap-grid.min.css.map | 0 .../bootstrap/css}/bootstrap-grid.rtl.css | 0 .../bootstrap/css}/bootstrap-grid.rtl.css.map | 0 .../bootstrap/css}/bootstrap-grid.rtl.min.css | 0 .../css}/bootstrap-grid.rtl.min.css.map | 0 .../bootstrap/css}/bootstrap-reboot.css | 0 .../bootstrap/css}/bootstrap-reboot.css.map | 0 .../bootstrap/css}/bootstrap-reboot.min.css | 0 .../bootstrap/css}/bootstrap-reboot.min.css.map | 0 .../bootstrap/css}/bootstrap-reboot.rtl.css | 0 .../bootstrap/css}/bootstrap-reboot.rtl.css.map | 0 .../bootstrap/css}/bootstrap-reboot.rtl.min.css | 0 .../css}/bootstrap-reboot.rtl.min.css.map | 0 .../bootstrap/css}/bootstrap-utilities.css | 0 .../bootstrap/css}/bootstrap-utilities.css.map | 0 .../bootstrap/css}/bootstrap-utilities.min.css | 0 .../css}/bootstrap-utilities.min.css.map | 0 .../bootstrap/css}/bootstrap-utilities.rtl.css | 0 .../css}/bootstrap-utilities.rtl.css.map | 0 .../css}/bootstrap-utilities.rtl.min.css | 0 .../css}/bootstrap-utilities.rtl.min.css.map | 0 .../bootstrap/css}/bootstrap.css | 0 .../bootstrap/css}/bootstrap.css.map | 0 .../bootstrap/css}/bootstrap.min.css | 0 .../bootstrap/css}/bootstrap.min.css.map | 0 .../bootstrap/css}/bootstrap.rtl.css | 0 .../bootstrap/css}/bootstrap.rtl.css.map | 0 .../bootstrap/css}/bootstrap.rtl.min.css | 0 .../bootstrap/css}/bootstrap.rtl.min.css.map | 0 .../bootstrap/js}/bootstrap.bundle.js | 0 .../bootstrap/js}/bootstrap.bundle.js.map | 0 .../bootstrap/js}/bootstrap.bundle.min.js | 0 .../bootstrap/js}/bootstrap.bundle.min.js.map | 0 .../bootstrap/js}/bootstrap.esm.js | 0 .../bootstrap/js}/bootstrap.esm.js.map | 0 .../bootstrap/js}/bootstrap.esm.min.js | 0 .../bootstrap/js}/bootstrap.esm.min.js.map | 0 .../bootstrap/js}/bootstrap.js | 0 .../bootstrap/js}/bootstrap.js.map | 0 .../bootstrap/js}/bootstrap.min.js | 0 .../bootstrap/js}/bootstrap.min.js.map | 0 vendor/flatpickr/flatpickr.min.css | 13 +++++++++++++ vendor/flatpickr/flatpickr.min.js | 2 ++ .../jquerry}/jquery-3.5.1.min.js | 0 vendor/jquerry/jquery-3.6.0.min.js | 2 ++ {js/vendor => vendor/jquerry}/jquery.growl.js | 0 {js/vendor => vendor/jquerry}/jquery.timeago.js | 0 51 files changed, 23 insertions(+), 10 deletions(-) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.min.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.rtl.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.rtl.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.rtl.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-grid.rtl.min.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.min.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.rtl.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.rtl.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.rtl.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-reboot.rtl.min.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.min.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.rtl.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.rtl.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.rtl.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap-utilities.rtl.min.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.min.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.rtl.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.rtl.css.map (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.rtl.min.css (100%) rename {css/vendor/bootstrap => vendor/bootstrap/css}/bootstrap.rtl.min.css.map (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.bundle.js (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.bundle.js.map (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.bundle.min.js (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.bundle.min.js.map (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.esm.js (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.esm.js.map (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.esm.min.js (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.esm.min.js.map (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.js (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.js.map (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.min.js (100%) rename {js/vendor/bootstrap => vendor/bootstrap/js}/bootstrap.min.js.map (100%) create mode 100644 vendor/flatpickr/flatpickr.min.css create mode 100644 vendor/flatpickr/flatpickr.min.js rename {js/vendor => vendor/jquerry}/jquery-3.5.1.min.js (100%) create mode 100644 vendor/jquerry/jquery-3.6.0.min.js rename {js/vendor => vendor/jquerry}/jquery.growl.js (100%) rename {js/vendor => vendor/jquerry}/jquery.timeago.js (100%) diff --git a/template.php b/template.php index 180eee8..d8bb071 100644 --- a/template.php +++ b/template.php @@ -63,7 +63,7 @@ class Template - + @@ -83,7 +83,7 @@ class Template - + - - + @@ -222,15 +221,12 @@ class Template
    - - - - + + - - + diff --git a/css/vendor/bootstrap/bootstrap-grid.css b/vendor/bootstrap/css/bootstrap-grid.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.css rename to vendor/bootstrap/css/bootstrap-grid.css diff --git a/css/vendor/bootstrap/bootstrap-grid.css.map b/vendor/bootstrap/css/bootstrap-grid.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.css.map rename to vendor/bootstrap/css/bootstrap-grid.css.map diff --git a/css/vendor/bootstrap/bootstrap-grid.min.css b/vendor/bootstrap/css/bootstrap-grid.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.min.css rename to vendor/bootstrap/css/bootstrap-grid.min.css diff --git a/css/vendor/bootstrap/bootstrap-grid.min.css.map b/vendor/bootstrap/css/bootstrap-grid.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.min.css.map rename to vendor/bootstrap/css/bootstrap-grid.min.css.map diff --git a/css/vendor/bootstrap/bootstrap-grid.rtl.css b/vendor/bootstrap/css/bootstrap-grid.rtl.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.rtl.css rename to vendor/bootstrap/css/bootstrap-grid.rtl.css diff --git a/css/vendor/bootstrap/bootstrap-grid.rtl.css.map b/vendor/bootstrap/css/bootstrap-grid.rtl.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.rtl.css.map rename to vendor/bootstrap/css/bootstrap-grid.rtl.css.map diff --git a/css/vendor/bootstrap/bootstrap-grid.rtl.min.css b/vendor/bootstrap/css/bootstrap-grid.rtl.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.rtl.min.css rename to vendor/bootstrap/css/bootstrap-grid.rtl.min.css diff --git a/css/vendor/bootstrap/bootstrap-grid.rtl.min.css.map b/vendor/bootstrap/css/bootstrap-grid.rtl.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-grid.rtl.min.css.map rename to vendor/bootstrap/css/bootstrap-grid.rtl.min.css.map diff --git a/css/vendor/bootstrap/bootstrap-reboot.css b/vendor/bootstrap/css/bootstrap-reboot.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.css rename to vendor/bootstrap/css/bootstrap-reboot.css diff --git a/css/vendor/bootstrap/bootstrap-reboot.css.map b/vendor/bootstrap/css/bootstrap-reboot.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.css.map rename to vendor/bootstrap/css/bootstrap-reboot.css.map diff --git a/css/vendor/bootstrap/bootstrap-reboot.min.css b/vendor/bootstrap/css/bootstrap-reboot.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.min.css rename to vendor/bootstrap/css/bootstrap-reboot.min.css diff --git a/css/vendor/bootstrap/bootstrap-reboot.min.css.map b/vendor/bootstrap/css/bootstrap-reboot.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.min.css.map rename to vendor/bootstrap/css/bootstrap-reboot.min.css.map diff --git a/css/vendor/bootstrap/bootstrap-reboot.rtl.css b/vendor/bootstrap/css/bootstrap-reboot.rtl.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.rtl.css rename to vendor/bootstrap/css/bootstrap-reboot.rtl.css diff --git a/css/vendor/bootstrap/bootstrap-reboot.rtl.css.map b/vendor/bootstrap/css/bootstrap-reboot.rtl.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.rtl.css.map rename to vendor/bootstrap/css/bootstrap-reboot.rtl.css.map diff --git a/css/vendor/bootstrap/bootstrap-reboot.rtl.min.css b/vendor/bootstrap/css/bootstrap-reboot.rtl.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.rtl.min.css rename to vendor/bootstrap/css/bootstrap-reboot.rtl.min.css diff --git a/css/vendor/bootstrap/bootstrap-reboot.rtl.min.css.map b/vendor/bootstrap/css/bootstrap-reboot.rtl.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-reboot.rtl.min.css.map rename to vendor/bootstrap/css/bootstrap-reboot.rtl.min.css.map diff --git a/css/vendor/bootstrap/bootstrap-utilities.css b/vendor/bootstrap/css/bootstrap-utilities.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.css rename to vendor/bootstrap/css/bootstrap-utilities.css diff --git a/css/vendor/bootstrap/bootstrap-utilities.css.map b/vendor/bootstrap/css/bootstrap-utilities.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.css.map rename to vendor/bootstrap/css/bootstrap-utilities.css.map diff --git a/css/vendor/bootstrap/bootstrap-utilities.min.css b/vendor/bootstrap/css/bootstrap-utilities.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.min.css rename to vendor/bootstrap/css/bootstrap-utilities.min.css diff --git a/css/vendor/bootstrap/bootstrap-utilities.min.css.map b/vendor/bootstrap/css/bootstrap-utilities.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.min.css.map rename to vendor/bootstrap/css/bootstrap-utilities.min.css.map diff --git a/css/vendor/bootstrap/bootstrap-utilities.rtl.css b/vendor/bootstrap/css/bootstrap-utilities.rtl.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.rtl.css rename to vendor/bootstrap/css/bootstrap-utilities.rtl.css diff --git a/css/vendor/bootstrap/bootstrap-utilities.rtl.css.map b/vendor/bootstrap/css/bootstrap-utilities.rtl.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.rtl.css.map rename to vendor/bootstrap/css/bootstrap-utilities.rtl.css.map diff --git a/css/vendor/bootstrap/bootstrap-utilities.rtl.min.css b/vendor/bootstrap/css/bootstrap-utilities.rtl.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.rtl.min.css rename to vendor/bootstrap/css/bootstrap-utilities.rtl.min.css diff --git a/css/vendor/bootstrap/bootstrap-utilities.rtl.min.css.map b/vendor/bootstrap/css/bootstrap-utilities.rtl.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap-utilities.rtl.min.css.map rename to vendor/bootstrap/css/bootstrap-utilities.rtl.min.css.map diff --git a/css/vendor/bootstrap/bootstrap.css b/vendor/bootstrap/css/bootstrap.css similarity index 100% rename from css/vendor/bootstrap/bootstrap.css rename to vendor/bootstrap/css/bootstrap.css diff --git a/css/vendor/bootstrap/bootstrap.css.map b/vendor/bootstrap/css/bootstrap.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap.css.map rename to vendor/bootstrap/css/bootstrap.css.map diff --git a/css/vendor/bootstrap/bootstrap.min.css b/vendor/bootstrap/css/bootstrap.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap.min.css rename to vendor/bootstrap/css/bootstrap.min.css diff --git a/css/vendor/bootstrap/bootstrap.min.css.map b/vendor/bootstrap/css/bootstrap.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap.min.css.map rename to vendor/bootstrap/css/bootstrap.min.css.map diff --git a/css/vendor/bootstrap/bootstrap.rtl.css b/vendor/bootstrap/css/bootstrap.rtl.css similarity index 100% rename from css/vendor/bootstrap/bootstrap.rtl.css rename to vendor/bootstrap/css/bootstrap.rtl.css diff --git a/css/vendor/bootstrap/bootstrap.rtl.css.map b/vendor/bootstrap/css/bootstrap.rtl.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap.rtl.css.map rename to vendor/bootstrap/css/bootstrap.rtl.css.map diff --git a/css/vendor/bootstrap/bootstrap.rtl.min.css b/vendor/bootstrap/css/bootstrap.rtl.min.css similarity index 100% rename from css/vendor/bootstrap/bootstrap.rtl.min.css rename to vendor/bootstrap/css/bootstrap.rtl.min.css diff --git a/css/vendor/bootstrap/bootstrap.rtl.min.css.map b/vendor/bootstrap/css/bootstrap.rtl.min.css.map similarity index 100% rename from css/vendor/bootstrap/bootstrap.rtl.min.css.map rename to vendor/bootstrap/css/bootstrap.rtl.min.css.map diff --git a/js/vendor/bootstrap/bootstrap.bundle.js b/vendor/bootstrap/js/bootstrap.bundle.js similarity index 100% rename from js/vendor/bootstrap/bootstrap.bundle.js rename to vendor/bootstrap/js/bootstrap.bundle.js diff --git a/js/vendor/bootstrap/bootstrap.bundle.js.map b/vendor/bootstrap/js/bootstrap.bundle.js.map similarity index 100% rename from js/vendor/bootstrap/bootstrap.bundle.js.map rename to vendor/bootstrap/js/bootstrap.bundle.js.map diff --git a/js/vendor/bootstrap/bootstrap.bundle.min.js b/vendor/bootstrap/js/bootstrap.bundle.min.js similarity index 100% rename from js/vendor/bootstrap/bootstrap.bundle.min.js rename to vendor/bootstrap/js/bootstrap.bundle.min.js diff --git a/js/vendor/bootstrap/bootstrap.bundle.min.js.map b/vendor/bootstrap/js/bootstrap.bundle.min.js.map similarity index 100% rename from js/vendor/bootstrap/bootstrap.bundle.min.js.map rename to vendor/bootstrap/js/bootstrap.bundle.min.js.map diff --git a/js/vendor/bootstrap/bootstrap.esm.js b/vendor/bootstrap/js/bootstrap.esm.js similarity index 100% rename from js/vendor/bootstrap/bootstrap.esm.js rename to vendor/bootstrap/js/bootstrap.esm.js diff --git a/js/vendor/bootstrap/bootstrap.esm.js.map b/vendor/bootstrap/js/bootstrap.esm.js.map similarity index 100% rename from js/vendor/bootstrap/bootstrap.esm.js.map rename to vendor/bootstrap/js/bootstrap.esm.js.map diff --git a/js/vendor/bootstrap/bootstrap.esm.min.js b/vendor/bootstrap/js/bootstrap.esm.min.js similarity index 100% rename from js/vendor/bootstrap/bootstrap.esm.min.js rename to vendor/bootstrap/js/bootstrap.esm.min.js diff --git a/js/vendor/bootstrap/bootstrap.esm.min.js.map b/vendor/bootstrap/js/bootstrap.esm.min.js.map similarity index 100% rename from js/vendor/bootstrap/bootstrap.esm.min.js.map rename to vendor/bootstrap/js/bootstrap.esm.min.js.map diff --git a/js/vendor/bootstrap/bootstrap.js b/vendor/bootstrap/js/bootstrap.js similarity index 100% rename from js/vendor/bootstrap/bootstrap.js rename to vendor/bootstrap/js/bootstrap.js diff --git a/js/vendor/bootstrap/bootstrap.js.map b/vendor/bootstrap/js/bootstrap.js.map similarity index 100% rename from js/vendor/bootstrap/bootstrap.js.map rename to vendor/bootstrap/js/bootstrap.js.map diff --git a/js/vendor/bootstrap/bootstrap.min.js b/vendor/bootstrap/js/bootstrap.min.js similarity index 100% rename from js/vendor/bootstrap/bootstrap.min.js rename to vendor/bootstrap/js/bootstrap.min.js diff --git a/js/vendor/bootstrap/bootstrap.min.js.map b/vendor/bootstrap/js/bootstrap.min.js.map similarity index 100% rename from js/vendor/bootstrap/bootstrap.min.js.map rename to vendor/bootstrap/js/bootstrap.min.js.map diff --git a/vendor/flatpickr/flatpickr.min.css b/vendor/flatpickr/flatpickr.min.css new file mode 100644 index 0000000..2b5da59 --- /dev/null +++ b/vendor/flatpickr/flatpickr.min.css @@ -0,0 +1,13 @@ +.flatpickr-calendar{background:transparent;opacity:0;display:none;text-align:center;visibility:hidden;padding:0;-webkit-animation:none;animation:none;direction:ltr;border:0;font-size:14px;line-height:24px;border-radius:5px;position:absolute;width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-touch-action:manipulation;touch-action:manipulation;background:#fff;-webkit-box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08)}.flatpickr-calendar.open,.flatpickr-calendar.inline{opacity:1;max-height:640px;visibility:visible}.flatpickr-calendar.open{display:inline-block;z-index:99999}.flatpickr-calendar.animate.open{-webkit-animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1);animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1)}.flatpickr-calendar.inline{display:block;position:relative;top:2px}.flatpickr-calendar.static{position:absolute;top:calc(100% + 2px)}.flatpickr-calendar.static.open{z-index:999;display:block}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7){-webkit-box-shadow:none !important;box-shadow:none !important}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1){-webkit-box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-calendar .hasWeeks .dayContainer,.flatpickr-calendar .hasTime .dayContainer{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.flatpickr-calendar .hasWeeks .dayContainer{border-left:0}.flatpickr-calendar.hasTime .flatpickr-time{height:40px;border-top:1px solid #e6e6e6}.flatpickr-calendar.noCalendar.hasTime .flatpickr-time{height:auto}.flatpickr-calendar:before,.flatpickr-calendar:after{position:absolute;display:block;pointer-events:none;border:solid transparent;content:'';height:0;width:0;left:22px}.flatpickr-calendar.rightMost:before,.flatpickr-calendar.arrowRight:before,.flatpickr-calendar.rightMost:after,.flatpickr-calendar.arrowRight:after{left:auto;right:22px}.flatpickr-calendar.arrowCenter:before,.flatpickr-calendar.arrowCenter:after{left:50%;right:50%}.flatpickr-calendar:before{border-width:5px;margin:0 -5px}.flatpickr-calendar:after{border-width:4px;margin:0 -4px}.flatpickr-calendar.arrowTop:before,.flatpickr-calendar.arrowTop:after{bottom:100%}.flatpickr-calendar.arrowTop:before{border-bottom-color:#e6e6e6}.flatpickr-calendar.arrowTop:after{border-bottom-color:#fff}.flatpickr-calendar.arrowBottom:before,.flatpickr-calendar.arrowBottom:after{top:100%}.flatpickr-calendar.arrowBottom:before{border-top-color:#e6e6e6}.flatpickr-calendar.arrowBottom:after{border-top-color:#fff}.flatpickr-calendar:focus{outline:0}.flatpickr-wrapper{position:relative;display:inline-block}.flatpickr-months{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flatpickr-months .flatpickr-month{background:transparent;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9);height:34px;line-height:1;text-align:center;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.flatpickr-months .flatpickr-prev-month,.flatpickr-months .flatpickr-next-month{text-decoration:none;cursor:pointer;position:absolute;top:0;height:34px;padding:10px;z-index:3;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9)}.flatpickr-months .flatpickr-prev-month.flatpickr-disabled,.flatpickr-months .flatpickr-next-month.flatpickr-disabled{display:none}.flatpickr-months .flatpickr-prev-month i,.flatpickr-months .flatpickr-next-month i{position:relative}.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,.flatpickr-months .flatpickr-next-month.flatpickr-prev-month{/* + /*rtl:begin:ignore*/left:0/* + /*rtl:end:ignore*/}/* + /*rtl:begin:ignore*/ +/* + /*rtl:end:ignore*/ +.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,.flatpickr-months .flatpickr-next-month.flatpickr-next-month{/* + /*rtl:begin:ignore*/right:0/* + /*rtl:end:ignore*/}/* + /*rtl:begin:ignore*/ +/* + /*rtl:end:ignore*/ +.flatpickr-months .flatpickr-prev-month:hover,.flatpickr-months .flatpickr-next-month:hover{color:#959ea9}.flatpickr-months .flatpickr-prev-month:hover svg,.flatpickr-months .flatpickr-next-month:hover svg{fill:#f64747}.flatpickr-months .flatpickr-prev-month svg,.flatpickr-months .flatpickr-next-month svg{width:14px;height:14px}.flatpickr-months .flatpickr-prev-month svg path,.flatpickr-months .flatpickr-next-month svg path{-webkit-transition:fill .1s;transition:fill .1s;fill:inherit}.numInputWrapper{position:relative;height:auto}.numInputWrapper input,.numInputWrapper span{display:inline-block}.numInputWrapper input{width:100%}.numInputWrapper input::-ms-clear{display:none}.numInputWrapper input::-webkit-outer-spin-button,.numInputWrapper input::-webkit-inner-spin-button{margin:0;-webkit-appearance:none}.numInputWrapper span{position:absolute;right:0;width:14px;padding:0 4px 0 2px;height:50%;line-height:50%;opacity:0;cursor:pointer;border:1px solid rgba(57,57,57,0.15);-webkit-box-sizing:border-box;box-sizing:border-box}.numInputWrapper span:hover{background:rgba(0,0,0,0.1)}.numInputWrapper span:active{background:rgba(0,0,0,0.2)}.numInputWrapper span:after{display:block;content:"";position:absolute}.numInputWrapper span.arrowUp{top:0;border-bottom:0}.numInputWrapper span.arrowUp:after{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:4px solid rgba(57,57,57,0.6);top:26%}.numInputWrapper span.arrowDown{top:50%}.numInputWrapper span.arrowDown:after{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(57,57,57,0.6);top:40%}.numInputWrapper span svg{width:inherit;height:auto}.numInputWrapper span svg path{fill:rgba(0,0,0,0.5)}.numInputWrapper:hover{background:rgba(0,0,0,0.05)}.numInputWrapper:hover span{opacity:1}.flatpickr-current-month{font-size:135%;line-height:inherit;font-weight:300;color:inherit;position:absolute;width:75%;left:12.5%;padding:7.48px 0 0 0;line-height:1;height:34px;display:inline-block;text-align:center;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.flatpickr-current-month span.cur-month{font-family:inherit;font-weight:700;color:inherit;display:inline-block;margin-left:.5ch;padding:0}.flatpickr-current-month span.cur-month:hover{background:rgba(0,0,0,0.05)}.flatpickr-current-month .numInputWrapper{width:6ch;width:7ch\0;display:inline-block}.flatpickr-current-month .numInputWrapper span.arrowUp:after{border-bottom-color:rgba(0,0,0,0.9)}.flatpickr-current-month .numInputWrapper span.arrowDown:after{border-top-color:rgba(0,0,0,0.9)}.flatpickr-current-month input.cur-year{background:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;cursor:text;padding:0 0 0 .5ch;margin:0;display:inline-block;font-size:inherit;font-family:inherit;font-weight:300;line-height:inherit;height:auto;border:0;border-radius:0;vertical-align:initial;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.flatpickr-current-month input.cur-year:focus{outline:0}.flatpickr-current-month input.cur-year[disabled],.flatpickr-current-month input.cur-year[disabled]:hover{font-size:100%;color:rgba(0,0,0,0.5);background:transparent;pointer-events:none}.flatpickr-current-month .flatpickr-monthDropdown-months{appearance:menulist;background:transparent;border:none;border-radius:0;box-sizing:border-box;color:inherit;cursor:pointer;font-size:inherit;font-family:inherit;font-weight:300;height:auto;line-height:inherit;margin:-1px 0 0 0;outline:none;padding:0 0 0 .5ch;position:relative;vertical-align:initial;-webkit-box-sizing:border-box;-webkit-appearance:menulist;-moz-appearance:menulist;width:auto}.flatpickr-current-month .flatpickr-monthDropdown-months:focus,.flatpickr-current-month .flatpickr-monthDropdown-months:active{outline:none}.flatpickr-current-month .flatpickr-monthDropdown-months:hover{background:rgba(0,0,0,0.05)}.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month{background-color:transparent;outline:none;padding:0}.flatpickr-weekdays{background:transparent;text-align:center;overflow:hidden;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:28px}.flatpickr-weekdays .flatpickr-weekdaycontainer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}span.flatpickr-weekday{cursor:default;font-size:90%;background:transparent;color:rgba(0,0,0,0.54);line-height:1;margin:0;text-align:center;display:block;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;font-weight:bolder}.dayContainer,.flatpickr-weeks{padding:1px 0 0 0}.flatpickr-days{position:relative;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;width:307.875px}.flatpickr-days:focus{outline:0}.dayContainer{padding:0;outline:0;text-align:left;width:307.875px;min-width:307.875px;max-width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;display:inline-block;display:-ms-flexbox;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-wrap:wrap;-ms-flex-pack:justify;-webkit-justify-content:space-around;justify-content:space-around;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}.dayContainer + .dayContainer{-webkit-box-shadow:-1px 0 0 #e6e6e6;box-shadow:-1px 0 0 #e6e6e6}.flatpickr-day{background:none;border:1px solid transparent;border-radius:150px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#393939;cursor:pointer;font-weight:400;width:14.2857143%;-webkit-flex-basis:14.2857143%;-ms-flex-preferred-size:14.2857143%;flex-basis:14.2857143%;max-width:39px;height:39px;line-height:39px;margin:0;display:inline-block;position:relative;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flatpickr-day.inRange,.flatpickr-day.prevMonthDay.inRange,.flatpickr-day.nextMonthDay.inRange,.flatpickr-day.today.inRange,.flatpickr-day.prevMonthDay.today.inRange,.flatpickr-day.nextMonthDay.today.inRange,.flatpickr-day:hover,.flatpickr-day.prevMonthDay:hover,.flatpickr-day.nextMonthDay:hover,.flatpickr-day:focus,.flatpickr-day.prevMonthDay:focus,.flatpickr-day.nextMonthDay:focus{cursor:pointer;outline:0;background:#e6e6e6;border-color:#e6e6e6}.flatpickr-day.today{border-color:#959ea9}.flatpickr-day.today:hover,.flatpickr-day.today:focus{border-color:#959ea9;background:#959ea9;color:#fff}.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,.flatpickr-day.selected.inRange,.flatpickr-day.startRange.inRange,.flatpickr-day.endRange.inRange,.flatpickr-day.selected:focus,.flatpickr-day.startRange:focus,.flatpickr-day.endRange:focus,.flatpickr-day.selected:hover,.flatpickr-day.startRange:hover,.flatpickr-day.endRange:hover,.flatpickr-day.selected.prevMonthDay,.flatpickr-day.startRange.prevMonthDay,.flatpickr-day.endRange.prevMonthDay,.flatpickr-day.selected.nextMonthDay,.flatpickr-day.startRange.nextMonthDay,.flatpickr-day.endRange.nextMonthDay{background:#569ff7;-webkit-box-shadow:none;box-shadow:none;color:#fff;border-color:#569ff7}.flatpickr-day.selected.startRange,.flatpickr-day.startRange.startRange,.flatpickr-day.endRange.startRange{border-radius:50px 0 0 50px}.flatpickr-day.selected.endRange,.flatpickr-day.startRange.endRange,.flatpickr-day.endRange.endRange{border-radius:0 50px 50px 0}.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)),.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n+1)),.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n+1)){-webkit-box-shadow:-10px 0 0 #569ff7;box-shadow:-10px 0 0 #569ff7}.flatpickr-day.selected.startRange.endRange,.flatpickr-day.startRange.startRange.endRange,.flatpickr-day.endRange.startRange.endRange{border-radius:50px}.flatpickr-day.inRange{border-radius:0;-webkit-box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-day.flatpickr-disabled,.flatpickr-day.flatpickr-disabled:hover,.flatpickr-day.prevMonthDay,.flatpickr-day.nextMonthDay,.flatpickr-day.notAllowed,.flatpickr-day.notAllowed.prevMonthDay,.flatpickr-day.notAllowed.nextMonthDay{color:rgba(57,57,57,0.3);background:transparent;border-color:transparent;cursor:default}.flatpickr-day.flatpickr-disabled,.flatpickr-day.flatpickr-disabled:hover{cursor:not-allowed;color:rgba(57,57,57,0.1)}.flatpickr-day.week.selected{border-radius:0;-webkit-box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7;box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7}.flatpickr-day.hidden{visibility:hidden}.rangeMode .flatpickr-day{margin-top:1px}.flatpickr-weekwrapper{float:left}.flatpickr-weekwrapper .flatpickr-weeks{padding:0 12px;-webkit-box-shadow:1px 0 0 #e6e6e6;box-shadow:1px 0 0 #e6e6e6}.flatpickr-weekwrapper .flatpickr-weekday{float:none;width:100%;line-height:28px}.flatpickr-weekwrapper span.flatpickr-day,.flatpickr-weekwrapper span.flatpickr-day:hover{display:block;width:100%;max-width:none;color:rgba(57,57,57,0.3);background:transparent;cursor:default;border:none}.flatpickr-innerContainer{display:block;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden}.flatpickr-rContainer{display:inline-block;padding:0;-webkit-box-sizing:border-box;box-sizing:border-box}.flatpickr-time{text-align:center;outline:0;display:block;height:0;line-height:40px;max-height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flatpickr-time:after{content:"";display:table;clear:both}.flatpickr-time .numInputWrapper{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;width:40%;height:40px;float:left}.flatpickr-time .numInputWrapper span.arrowUp:after{border-bottom-color:#393939}.flatpickr-time .numInputWrapper span.arrowDown:after{border-top-color:#393939}.flatpickr-time.hasSeconds .numInputWrapper{width:26%}.flatpickr-time.time24hr .numInputWrapper{width:49%}.flatpickr-time input{background:transparent;-webkit-box-shadow:none;box-shadow:none;border:0;border-radius:0;text-align:center;margin:0;padding:0;height:inherit;line-height:inherit;color:#393939;font-size:14px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.flatpickr-time input.flatpickr-hour{font-weight:bold}.flatpickr-time input.flatpickr-minute,.flatpickr-time input.flatpickr-second{font-weight:400}.flatpickr-time input:focus{outline:0;border:0}.flatpickr-time .flatpickr-time-separator,.flatpickr-time .flatpickr-am-pm{height:inherit;float:left;line-height:inherit;color:#393939;font-weight:bold;width:2%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.flatpickr-time .flatpickr-am-pm{outline:0;width:18%;cursor:pointer;text-align:center;font-weight:400}.flatpickr-time input:hover,.flatpickr-time .flatpickr-am-pm:hover,.flatpickr-time input:focus,.flatpickr-time .flatpickr-am-pm:focus{background:#eee}.flatpickr-input[readonly]{cursor:pointer}@-webkit-keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}} \ No newline at end of file diff --git a/vendor/flatpickr/flatpickr.min.js b/vendor/flatpickr/flatpickr.min.js new file mode 100644 index 0000000..345297f --- /dev/null +++ b/vendor/flatpickr/flatpickr.min.js @@ -0,0 +1,2 @@ +/* flatpickr v4.6.9,, @license MIT */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).flatpickr=t()}(this,(function(){"use strict";var e=function(){return(e=Object.assign||function(e){for(var t,n=1,a=arguments.length;n",noCalendar:!1,now:new Date,onChange:[],onClose:[],onDayCreate:[],onDestroy:[],onKeyDown:[],onMonthChange:[],onOpen:[],onParseConfig:[],onReady:[],onValueUpdate:[],onYearChange:[],onPreCalendarPosition:[],plugins:[],position:"auto",positionElement:void 0,prevArrow:"",shorthandCurrentMonth:!1,showMonths:1,static:!1,time_24hr:!1,weekNumbers:!1,wrap:!1},i={weekdays:{shorthand:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],longhand:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},months:{shorthand:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],longhand:["January","February","March","April","May","June","July","August","September","October","November","December"]},daysInMonth:[31,28,31,30,31,30,31,31,30,31,30,31],firstDayOfWeek:0,ordinal:function(e){var t=e%100;if(t>3&&t<21)return"th";switch(t%10){case 1:return"st";case 2:return"nd";case 3:return"rd";default:return"th"}},rangeSeparator:" to ",weekAbbreviation:"Wk",scrollTitle:"Scroll to increment",toggleTitle:"Click to toggle",amPM:["AM","PM"],yearAriaLabel:"Year",monthAriaLabel:"Month",hourAriaLabel:"Hour",minuteAriaLabel:"Minute",time_24hr:!1},o=function(e,t){return void 0===t&&(t=2),("000"+e).slice(-1*t)},r=function(e){return!0===e?1:0};function l(e,t){var n;return function(){var a=this;clearTimeout(n),n=setTimeout((function(){return e.apply(a,arguments)}),t)}}var c=function(e){return e instanceof Array?e:[e]};function d(e,t,n){if(!0===n)return e.classList.add(t);e.classList.remove(t)}function s(e,t,n){var a=window.document.createElement(e);return t=t||"",n=n||"",a.className=t,void 0!==n&&(a.textContent=n),a}function u(e){for(;e.firstChild;)e.removeChild(e.firstChild)}function f(e,t){return t(e)?e:e.parentNode?f(e.parentNode,t):void 0}function m(e,t){var n=s("div","numInputWrapper"),a=s("input","numInput "+e),i=s("span","arrowUp"),o=s("span","arrowDown");if(-1===navigator.userAgent.indexOf("MSIE 9.0")?a.type="number":(a.type="text",a.pattern="\\d*"),void 0!==t)for(var r in t)a.setAttribute(r,t[r]);return n.appendChild(a),n.appendChild(i),n.appendChild(o),n}function g(e){try{return"function"==typeof e.composedPath?e.composedPath()[0]:e.target}catch(t){return e.target}}var p=function(){},h=function(e,t,n){return n.months[t?"shorthand":"longhand"][e]},v={D:p,F:function(e,t,n){e.setMonth(n.months.longhand.indexOf(t))},G:function(e,t){e.setHours(parseFloat(t))},H:function(e,t){e.setHours(parseFloat(t))},J:function(e,t){e.setDate(parseFloat(t))},K:function(e,t,n){e.setHours(e.getHours()%12+12*r(new RegExp(n.amPM[1],"i").test(t)))},M:function(e,t,n){e.setMonth(n.months.shorthand.indexOf(t))},S:function(e,t){e.setSeconds(parseFloat(t))},U:function(e,t){return new Date(1e3*parseFloat(t))},W:function(e,t,n){var a=parseInt(t),i=new Date(e.getFullYear(),0,2+7*(a-1),0,0,0,0);return i.setDate(i.getDate()-i.getDay()+n.firstDayOfWeek),i},Y:function(e,t){e.setFullYear(parseFloat(t))},Z:function(e,t){return new Date(t)},d:function(e,t){e.setDate(parseFloat(t))},h:function(e,t){e.setHours(parseFloat(t))},i:function(e,t){e.setMinutes(parseFloat(t))},j:function(e,t){e.setDate(parseFloat(t))},l:p,m:function(e,t){e.setMonth(parseFloat(t)-1)},n:function(e,t){e.setMonth(parseFloat(t)-1)},s:function(e,t){e.setSeconds(parseFloat(t))},u:function(e,t){return new Date(parseFloat(t))},w:p,y:function(e,t){e.setFullYear(2e3+parseFloat(t))}},D={D:"(\\w+)",F:"(\\w+)",G:"(\\d\\d|\\d)",H:"(\\d\\d|\\d)",J:"(\\d\\d|\\d)\\w+",K:"",M:"(\\w+)",S:"(\\d\\d|\\d)",U:"(.+)",W:"(\\d\\d|\\d)",Y:"(\\d{4})",Z:"(.+)",d:"(\\d\\d|\\d)",h:"(\\d\\d|\\d)",i:"(\\d\\d|\\d)",j:"(\\d\\d|\\d)",l:"(\\w+)",m:"(\\d\\d|\\d)",n:"(\\d\\d|\\d)",s:"(\\d\\d|\\d)",u:"(.+)",w:"(\\d\\d|\\d)",y:"(\\d{2})"},w={Z:function(e){return e.toISOString()},D:function(e,t,n){return t.weekdays.shorthand[w.w(e,t,n)]},F:function(e,t,n){return h(w.n(e,t,n)-1,!1,t)},G:function(e,t,n){return o(w.h(e,t,n))},H:function(e){return o(e.getHours())},J:function(e,t){return void 0!==t.ordinal?e.getDate()+t.ordinal(e.getDate()):e.getDate()},K:function(e,t){return t.amPM[r(e.getHours()>11)]},M:function(e,t){return h(e.getMonth(),!0,t)},S:function(e){return o(e.getSeconds())},U:function(e){return e.getTime()/1e3},W:function(e,t,n){return n.getWeek(e)},Y:function(e){return o(e.getFullYear(),4)},d:function(e){return o(e.getDate())},h:function(e){return e.getHours()%12?e.getHours()%12:12},i:function(e){return o(e.getMinutes())},j:function(e){return e.getDate()},l:function(e,t){return t.weekdays.longhand[e.getDay()]},m:function(e){return o(e.getMonth()+1)},n:function(e){return e.getMonth()+1},s:function(e){return e.getSeconds()},u:function(e){return e.getTime()},w:function(e){return e.getDay()},y:function(e){return String(e.getFullYear()).substring(2)}},b=function(e){var t=e.config,n=void 0===t?a:t,o=e.l10n,r=void 0===o?i:o,l=e.isMobile,c=void 0!==l&&l;return function(e,t,a){var i=a||r;return void 0===n.formatDate||c?t.split("").map((function(t,a,o){return w[t]&&"\\"!==o[a-1]?w[t](e,i,n):"\\"!==t?t:""})).join(""):n.formatDate(e,t,i)}},C=function(e){var t=e.config,n=void 0===t?a:t,o=e.l10n,r=void 0===o?i:o;return function(e,t,i,o){if(0===e||e){var l,c=o||r,d=e;if(e instanceof Date)l=new Date(e.getTime());else if("string"!=typeof e&&void 0!==e.toFixed)l=new Date(e);else if("string"==typeof e){var s=t||(n||a).dateFormat,u=String(e).trim();if("today"===u)l=new Date,i=!0;else if(/Z$/.test(u)||/GMT$/.test(u))l=new Date(e);else if(n&&n.parseDate)l=n.parseDate(e,s);else{l=n&&n.noCalendar?new Date((new Date).setHours(0,0,0,0)):new Date((new Date).getFullYear(),0,1,0,0,0,0);for(var f=void 0,m=[],g=0,p=0,h="";g=0?new Date:new Date(w.config.minDate.getTime()),n=x(w.config);t.setHours(n.hours,n.minutes,n.seconds,t.getMilliseconds()),w.selectedDates=[t],w.latestSelectedDateObj=t}void 0!==e&&"blur"!==e.type&&function(e){e.preventDefault();var t="keydown"===e.type,n=g(e),a=n;void 0!==w.amPM&&n===w.amPM&&(w.amPM.textContent=w.l10n.amPM[r(w.amPM.textContent===w.l10n.amPM[0])]);var i=parseFloat(a.getAttribute("min")),l=parseFloat(a.getAttribute("max")),c=parseFloat(a.getAttribute("step")),d=parseInt(a.value,10),s=e.delta||(t?38===e.which?1:-1:0),u=d+c*s;if(void 0!==a.value&&2===a.value.length){var f=a===w.hourElement,m=a===w.minuteElement;ul&&(u=a===w.hourElement?u-l-r(!w.amPM):i,m&&j(void 0,1,w.hourElement)),w.amPM&&f&&(1===c?u+d===23:Math.abs(u-d)>c)&&(w.amPM.textContent=w.l10n.amPM[r(w.amPM.textContent===w.l10n.amPM[0])]),a.value=o(u)}}(e);var a=w._input.value;S(),be(),w._input.value!==a&&w._debouncedChange()}function S(){if(void 0!==w.hourElement&&void 0!==w.minuteElement){var e,t,n=(parseInt(w.hourElement.value.slice(-2),10)||0)%24,a=(parseInt(w.minuteElement.value,10)||0)%60,i=void 0!==w.secondElement?(parseInt(w.secondElement.value,10)||0)%60:0;void 0!==w.amPM&&(e=n,t=w.amPM.textContent,n=e%12+12*r(t===w.l10n.amPM[1]));var o=void 0!==w.config.minTime||w.config.minDate&&w.minDateHasTime&&w.latestSelectedDateObj&&0===M(w.latestSelectedDateObj,w.config.minDate,!0);if(void 0!==w.config.maxTime||w.config.maxDate&&w.maxDateHasTime&&w.latestSelectedDateObj&&0===M(w.latestSelectedDateObj,w.config.maxDate,!0)){var l=void 0!==w.config.maxTime?w.config.maxTime:w.config.maxDate;(n=Math.min(n,l.getHours()))===l.getHours()&&(a=Math.min(a,l.getMinutes())),a===l.getMinutes()&&(i=Math.min(i,l.getSeconds()))}if(o){var c=void 0!==w.config.minTime?w.config.minTime:w.config.minDate;(n=Math.max(n,c.getHours()))===c.getHours()&&a=12)]),void 0!==w.secondElement&&(w.secondElement.value=o(n)))}function F(e){var t=g(e),n=parseInt(t.value)+(e.delta||0);(n/1e3>1||"Enter"===e.key&&!/[^\d]/.test(n.toString()))&&Q(n)}function A(e,t,n,a){return t instanceof Array?t.forEach((function(t){return A(e,t,n,a)})):e instanceof Array?e.forEach((function(e){return A(e,t,n,a)})):(e.addEventListener(t,n,a),void w._handlers.push({remove:function(){return e.removeEventListener(t,n)}}))}function N(){pe("onChange")}function P(e,t){var n=void 0!==e?w.parseDate(e):w.latestSelectedDateObj||(w.config.minDate&&w.config.minDate>w.now?w.config.minDate:w.config.maxDate&&w.config.maxDate=0&&M(e,w.selectedDates[1])<=0)}(t)&&!ve(t)&&o.classList.add("inRange"),w.weekNumbers&&1===w.config.showMonths&&"prevMonthDay"!==e&&n%7==1&&w.weekNumbers.insertAdjacentHTML("beforeend",""+w.config.getWeek(t)+""),pe("onDayCreate",o),o}function L(e){e.focus(),"range"===w.config.mode&&ae(e)}function W(e){for(var t=e>0?0:w.config.showMonths-1,n=e>0?w.config.showMonths:-1,a=t;a!=n;a+=e)for(var i=w.daysContainer.children[a],o=e>0?0:i.children.length-1,r=e>0?i.children.length:-1,l=o;l!=r;l+=e){var c=i.children[l];if(-1===c.className.indexOf("hidden")&&X(c.dateObj))return c}}function R(e,t){var n=ee(document.activeElement||document.body),a=void 0!==e?e:n?document.activeElement:void 0!==w.selectedDateElem&&ee(w.selectedDateElem)?w.selectedDateElem:void 0!==w.todayDateElem&&ee(w.todayDateElem)?w.todayDateElem:W(t>0?1:-1);void 0===a?w._input.focus():n?function(e,t){for(var n=-1===e.className.indexOf("Month")?e.dateObj.getMonth():w.currentMonth,a=t>0?w.config.showMonths:-1,i=t>0?1:-1,o=n-w.currentMonth;o!=a;o+=i)for(var r=w.daysContainer.children[o],l=n-w.currentMonth===o?e.$i+t:t<0?r.children.length-1:0,c=r.children.length,d=l;d>=0&&d0?c:-1);d+=i){var s=r.children[d];if(-1===s.className.indexOf("hidden")&&X(s.dateObj)&&Math.abs(e.$i-d)>=Math.abs(t))return L(s)}w.changeMonth(i),R(W(i),0)}(a,t):L(a)}function B(e,t){for(var n=(new Date(e,t,1).getDay()-w.l10n.firstDayOfWeek+7)%7,a=w.utils.getDaysInMonth((t-1+12)%12,e),i=w.utils.getDaysInMonth(t,e),o=window.document.createDocumentFragment(),r=w.config.showMonths>1,l=r?"prevMonthDay hidden":"prevMonthDay",c=r?"nextMonthDay hidden":"nextMonthDay",d=a+1-n,u=0;d<=a;d++,u++)o.appendChild(H(l,new Date(e,t-1,d),d,u));for(d=1;d<=i;d++,u++)o.appendChild(H("",new Date(e,t,d),d,u));for(var f=i+1;f<=42-n&&(1===w.config.showMonths||u%7!=0);f++,u++)o.appendChild(H(c,new Date(e,t+1,f%i),f,u));var m=s("div","dayContainer");return m.appendChild(o),m}function J(){if(void 0!==w.daysContainer){u(w.daysContainer),w.weekNumbers&&u(w.weekNumbers);for(var e=document.createDocumentFragment(),t=0;t1||"dropdown"!==w.config.monthSelectorType)){var e=function(e){return!(void 0!==w.config.minDate&&w.currentYear===w.config.minDate.getFullYear()&&ew.config.maxDate.getMonth())};w.monthsDropdownContainer.tabIndex=-1,w.monthsDropdownContainer.innerHTML="";for(var t=0;t<12;t++)if(e(t)){var n=s("option","flatpickr-monthDropdown-month");n.value=new Date(w.currentYear,t).getMonth().toString(),n.textContent=h(t,w.config.shorthandCurrentMonth,w.l10n),n.tabIndex=-1,w.currentMonth===t&&(n.selected=!0),w.monthsDropdownContainer.appendChild(n)}}}function U(){var e,t=s("div","flatpickr-month"),n=window.document.createDocumentFragment();w.config.showMonths>1||"static"===w.config.monthSelectorType?e=s("span","cur-month"):(w.monthsDropdownContainer=s("select","flatpickr-monthDropdown-months"),w.monthsDropdownContainer.setAttribute("aria-label",w.l10n.monthAriaLabel),A(w.monthsDropdownContainer,"change",(function(e){var t=g(e),n=parseInt(t.value,10);w.changeMonth(n-w.currentMonth),pe("onMonthChange")})),K(),e=w.monthsDropdownContainer);var a=m("cur-year",{tabindex:"-1"}),i=a.getElementsByTagName("input")[0];i.setAttribute("aria-label",w.l10n.yearAriaLabel),w.config.minDate&&i.setAttribute("min",w.config.minDate.getFullYear().toString()),w.config.maxDate&&(i.setAttribute("max",w.config.maxDate.getFullYear().toString()),i.disabled=!!w.config.minDate&&w.config.minDate.getFullYear()===w.config.maxDate.getFullYear());var o=s("div","flatpickr-current-month");return o.appendChild(e),o.appendChild(a),n.appendChild(o),t.appendChild(n),{container:t,yearElement:i,monthElement:e}}function q(){u(w.monthNav),w.monthNav.appendChild(w.prevMonthNav),w.config.showMonths&&(w.yearElements=[],w.monthElements=[]);for(var e=w.config.showMonths;e--;){var t=U();w.yearElements.push(t.yearElement),w.monthElements.push(t.monthElement),w.monthNav.appendChild(t.container)}w.monthNav.appendChild(w.nextMonthNav)}function $(){w.weekdayContainer?u(w.weekdayContainer):w.weekdayContainer=s("div","flatpickr-weekdays");for(var e=w.config.showMonths;e--;){var t=s("div","flatpickr-weekdaycontainer");w.weekdayContainer.appendChild(t)}return z(),w.weekdayContainer}function z(){if(w.weekdayContainer){var e=w.l10n.firstDayOfWeek,n=t(w.l10n.weekdays.shorthand);e>0&&e\n "+n.join("")+"\n \n "}}function G(e,t){void 0===t&&(t=!0);var n=t?e:e-w.currentMonth;n<0&&!0===w._hidePrevMonthArrow||n>0&&!0===w._hideNextMonthArrow||(w.currentMonth+=n,(w.currentMonth<0||w.currentMonth>11)&&(w.currentYear+=w.currentMonth>11?1:-1,w.currentMonth=(w.currentMonth+12)%12,pe("onYearChange"),K()),J(),pe("onMonthChange"),De())}function V(e){return!(!w.config.appendTo||!w.config.appendTo.contains(e))||w.calendarContainer.contains(e)}function Z(e){if(w.isOpen&&!w.config.inline){var t=g(e),n=V(t),a=t===w.input||t===w.altInput||w.element.contains(t)||e.path&&e.path.indexOf&&(~e.path.indexOf(w.input)||~e.path.indexOf(w.altInput)),i="blur"===e.type?a&&e.relatedTarget&&!V(e.relatedTarget):!a&&!n&&!V(e.relatedTarget),o=!w.config.ignoredFocusElements.some((function(e){return e.contains(t)}));i&&o&&(void 0!==w.timeContainer&&void 0!==w.minuteElement&&void 0!==w.hourElement&&""!==w.input.value&&void 0!==w.input.value&&I(),w.close(),w.config&&"range"===w.config.mode&&1===w.selectedDates.length&&(w.clear(!1),w.redraw()))}}function Q(e){if(!(!e||w.config.minDate&&ew.config.maxDate.getFullYear())){var t=e,n=w.currentYear!==t;w.currentYear=t||w.currentYear,w.config.maxDate&&w.currentYear===w.config.maxDate.getFullYear()?w.currentMonth=Math.min(w.config.maxDate.getMonth(),w.currentMonth):w.config.minDate&&w.currentYear===w.config.minDate.getFullYear()&&(w.currentMonth=Math.max(w.config.minDate.getMonth(),w.currentMonth)),n&&(w.redraw(),pe("onYearChange"),K())}}function X(e,t){var n;void 0===t&&(t=!0);var a=w.parseDate(e,void 0,t);if(w.config.minDate&&a&&M(a,w.config.minDate,void 0!==t?t:!w.minDateHasTime)<0||w.config.maxDate&&a&&M(a,w.config.maxDate,void 0!==t?t:!w.maxDateHasTime)>0)return!1;if(!w.config.enable&&0===w.config.disable.length)return!0;if(void 0===a)return!1;for(var i=!!w.config.enable,o=null!==(n=w.config.enable)&&void 0!==n?n:w.config.disable,r=0,l=void 0;r=l.from.getTime()&&a.getTime()<=l.to.getTime())return i}return!i}function ee(e){return void 0!==w.daysContainer&&(-1===e.className.indexOf("hidden")&&-1===e.className.indexOf("flatpickr-disabled")&&w.daysContainer.contains(e))}function te(e){!(e.target===w._input)||!(w.selectedDates.length>0||w._input.value.length>0)||e.relatedTarget&&V(e.relatedTarget)||w.setDate(w._input.value,!0,e.target===w.altInput?w.config.altFormat:w.config.dateFormat)}function ne(e){var t=g(e),n=w.config.wrap?p.contains(t):t===w._input,a=w.config.allowInput,i=w.isOpen&&(!a||!n),o=w.config.inline&&n&&!a;if(13===e.keyCode&&n){if(a)return w.setDate(w._input.value,!0,t===w.altInput?w.config.altFormat:w.config.dateFormat),t.blur();w.open()}else if(V(t)||i||o){var r=!!w.timeContainer&&w.timeContainer.contains(t);switch(e.keyCode){case 13:r?(e.preventDefault(),I(),se()):ue(e);break;case 27:e.preventDefault(),se();break;case 8:case 46:n&&!w.config.allowInput&&(e.preventDefault(),w.clear());break;case 37:case 39:if(r||n)w.hourElement&&w.hourElement.focus();else if(e.preventDefault(),void 0!==w.daysContainer&&(!1===a||document.activeElement&&ee(document.activeElement))){var l=39===e.keyCode?1:-1;e.ctrlKey?(e.stopPropagation(),G(l),R(W(1),0)):R(void 0,l)}break;case 38:case 40:e.preventDefault();var c=40===e.keyCode?1:-1;w.daysContainer&&void 0!==t.$i||t===w.input||t===w.altInput?e.ctrlKey?(e.stopPropagation(),Q(w.currentYear-c),R(W(1),0)):r||R(void 0,7*c):t===w.currentYearElement?Q(w.currentYear-c):w.config.enableTime&&(!r&&w.hourElement&&w.hourElement.focus(),I(e),w._debouncedChange());break;case 9:if(r){var d=[w.hourElement,w.minuteElement,w.secondElement,w.amPM].concat(w.pluginElements).filter((function(e){return e})),s=d.indexOf(t);if(-1!==s){var u=d[s+(e.shiftKey?-1:1)];e.preventDefault(),(u||w._input).focus()}}else!w.config.noCalendar&&w.daysContainer&&w.daysContainer.contains(t)&&e.shiftKey&&(e.preventDefault(),w._input.focus())}}if(void 0!==w.amPM&&t===w.amPM)switch(e.key){case w.l10n.amPM[0].charAt(0):case w.l10n.amPM[0].charAt(0).toLowerCase():w.amPM.textContent=w.l10n.amPM[0],S(),be();break;case w.l10n.amPM[1].charAt(0):case w.l10n.amPM[1].charAt(0).toLowerCase():w.amPM.textContent=w.l10n.amPM[1],S(),be()}(n||V(t))&&pe("onKeyDown",e)}function ae(e){if(1===w.selectedDates.length&&(!e||e.classList.contains("flatpickr-day")&&!e.classList.contains("flatpickr-disabled"))){for(var t=e?e.dateObj.getTime():w.days.firstElementChild.dateObj.getTime(),n=w.parseDate(w.selectedDates[0],void 0,!0).getTime(),a=Math.min(t,w.selectedDates[0].getTime()),i=Math.max(t,w.selectedDates[0].getTime()),o=!1,r=0,l=0,c=a;ca&&cr)?r=c:c>n&&(!l||c0&&m0&&m>l;return g?(f.classList.add("notAllowed"),["inRange","startRange","endRange"].forEach((function(e){f.classList.remove(e)})),"continue"):o&&!g?"continue":(["startRange","inRange","endRange","notAllowed"].forEach((function(e){f.classList.remove(e)})),void(void 0!==e&&(e.classList.add(t<=w.selectedDates[0].getTime()?"startRange":"endRange"),nt&&m===n&&f.classList.add("endRange"),m>=r&&(0===l||m<=l)&&(d=n,u=t,(c=m)>Math.min(d,u)&&c0||n.getMinutes()>0||n.getSeconds()>0),w.selectedDates&&(w.selectedDates=w.selectedDates.filter((function(e){return X(e)})),w.selectedDates.length||"min"!==e||_(n),be()),w.daysContainer&&(de(),void 0!==n?w.currentYearElement[e]=n.getFullYear().toString():w.currentYearElement.removeAttribute(e),w.currentYearElement.disabled=!!a&&void 0!==n&&a.getFullYear()===n.getFullYear())}}function re(){return w.config.wrap?p.querySelector("[data-input]"):p}function le(){"object"!=typeof w.config.locale&&void 0===T.l10ns[w.config.locale]&&w.config.errorHandler(new Error("flatpickr: invalid locale "+w.config.locale)),w.l10n=e(e({},T.l10ns.default),"object"==typeof w.config.locale?w.config.locale:"default"!==w.config.locale?T.l10ns[w.config.locale]:void 0),D.K="("+w.l10n.amPM[0]+"|"+w.l10n.amPM[1]+"|"+w.l10n.amPM[0].toLowerCase()+"|"+w.l10n.amPM[1].toLowerCase()+")",void 0===e(e({},v),JSON.parse(JSON.stringify(p.dataset||{}))).time_24hr&&void 0===T.defaultConfig.time_24hr&&(w.config.time_24hr=w.l10n.time_24hr),w.formatDate=b(w),w.parseDate=C({config:w.config,l10n:w.l10n})}function ce(e){if("function"!=typeof w.config.position){if(void 0!==w.calendarContainer){pe("onPreCalendarPosition");var t=e||w._positionElement,n=Array.prototype.reduce.call(w.calendarContainer.children,(function(e,t){return e+t.offsetHeight}),0),a=w.calendarContainer.offsetWidth,i=w.config.position.split(" "),o=i[0],r=i.length>1?i[1]:null,l=t.getBoundingClientRect(),c=window.innerHeight-l.bottom,s="above"===o||"below"!==o&&cn,u=window.pageYOffset+l.top+(s?-n-2:t.offsetHeight+2);if(d(w.calendarContainer,"arrowTop",!s),d(w.calendarContainer,"arrowBottom",s),!w.config.inline){var f=window.pageXOffset+l.left,m=!1,g=!1;"center"===r?(f-=(a-l.width)/2,m=!0):"right"===r&&(f-=a-l.width,g=!0),d(w.calendarContainer,"arrowLeft",!m&&!g),d(w.calendarContainer,"arrowCenter",m),d(w.calendarContainer,"arrowRight",g);var p=window.document.body.offsetWidth-(window.pageXOffset+l.right),h=f+a>window.document.body.offsetWidth,v=p+a>window.document.body.offsetWidth;if(d(w.calendarContainer,"rightMost",h),!w.config.static)if(w.calendarContainer.style.top=u+"px",h)if(v){var D=function(){for(var e=null,t=0;tw.currentMonth+w.config.showMonths-1)&&"range"!==w.config.mode;if(w.selectedDateElem=n,"single"===w.config.mode)w.selectedDates=[a];else if("multiple"===w.config.mode){var o=ve(a);o?w.selectedDates.splice(parseInt(o),1):w.selectedDates.push(a)}else"range"===w.config.mode&&(2===w.selectedDates.length&&w.clear(!1,!1),w.latestSelectedDateObj=a,w.selectedDates.push(a),0!==M(a,w.selectedDates[0],!0)&&w.selectedDates.sort((function(e,t){return e.getTime()-t.getTime()})));if(S(),i){var r=w.currentYear!==a.getFullYear();w.currentYear=a.getFullYear(),w.currentMonth=a.getMonth(),r&&(pe("onYearChange"),K()),pe("onMonthChange")}if(De(),J(),be(),i||"range"===w.config.mode||1!==w.config.showMonths?void 0!==w.selectedDateElem&&void 0===w.hourElement&&w.selectedDateElem&&w.selectedDateElem.focus():L(n),void 0!==w.hourElement&&void 0!==w.hourElement&&w.hourElement.focus(),w.config.closeOnSelect){var l="single"===w.config.mode&&!w.config.enableTime,c="range"===w.config.mode&&2===w.selectedDates.length&&!w.config.enableTime;(l||c)&&se()}N()}}w.parseDate=C({config:w.config,l10n:w.l10n}),w._handlers=[],w.pluginElements=[],w.loadedPlugins=[],w._bind=A,w._setHoursFromDate=_,w._positionCalendar=ce,w.changeMonth=G,w.changeYear=Q,w.clear=function(e,t){void 0===e&&(e=!0);void 0===t&&(t=!0);w.input.value="",void 0!==w.altInput&&(w.altInput.value="");void 0!==w.mobileInput&&(w.mobileInput.value="");w.selectedDates=[],w.latestSelectedDateObj=void 0,!0===t&&(w.currentYear=w._initialDate.getFullYear(),w.currentMonth=w._initialDate.getMonth());if(!0===w.config.enableTime){var n=x(w.config),a=n.hours,i=n.minutes,o=n.seconds;O(a,i,o)}w.redraw(),e&&pe("onChange")},w.close=function(){w.isOpen=!1,w.isMobile||(void 0!==w.calendarContainer&&w.calendarContainer.classList.remove("open"),void 0!==w._input&&w._input.classList.remove("active"));pe("onClose")},w._createElement=s,w.destroy=function(){void 0!==w.config&&pe("onDestroy");for(var e=w._handlers.length;e--;)w._handlers[e].remove();if(w._handlers=[],w.mobileInput)w.mobileInput.parentNode&&w.mobileInput.parentNode.removeChild(w.mobileInput),w.mobileInput=void 0;else if(w.calendarContainer&&w.calendarContainer.parentNode)if(w.config.static&&w.calendarContainer.parentNode){var t=w.calendarContainer.parentNode;if(t.lastChild&&t.removeChild(t.lastChild),t.parentNode){for(;t.firstChild;)t.parentNode.insertBefore(t.firstChild,t);t.parentNode.removeChild(t)}}else w.calendarContainer.parentNode.removeChild(w.calendarContainer);w.altInput&&(w.input.type="text",w.altInput.parentNode&&w.altInput.parentNode.removeChild(w.altInput),delete w.altInput);w.input&&(w.input.type=w.input._type,w.input.classList.remove("flatpickr-input"),w.input.removeAttribute("readonly"));["_showTimeInput","latestSelectedDateObj","_hideNextMonthArrow","_hidePrevMonthArrow","__hideNextMonthArrow","__hidePrevMonthArrow","isMobile","isOpen","selectedDateElem","minDateHasTime","maxDateHasTime","days","daysContainer","_input","_positionElement","innerContainer","rContainer","monthNav","todayDateElem","calendarContainer","weekdayContainer","prevMonthNav","nextMonthNav","monthsDropdownContainer","currentMonthElement","currentYearElement","navigationCurrentMonth","selectedDateElem","config"].forEach((function(e){try{delete w[e]}catch(e){}}))},w.isEnabled=X,w.jumpToDate=P,w.open=function(e,t){void 0===t&&(t=w._positionElement);if(!0===w.isMobile){if(e){e.preventDefault();var n=g(e);n&&n.blur()}return void 0!==w.mobileInput&&(w.mobileInput.focus(),w.mobileInput.click()),void pe("onOpen")}if(w._input.disabled||w.config.inline)return;var a=w.isOpen;w.isOpen=!0,a||(w.calendarContainer.classList.add("open"),w._input.classList.add("active"),pe("onOpen"),ce(t));!0===w.config.enableTime&&!0===w.config.noCalendar&&(!1!==w.config.allowInput||void 0!==e&&w.timeContainer.contains(e.relatedTarget)||setTimeout((function(){return w.hourElement.select()}),50))},w.redraw=de,w.set=function(e,t){if(null!==e&&"object"==typeof e)for(var a in Object.assign(w.config,e),e)void 0!==fe[a]&&fe[a].forEach((function(e){return e()}));else w.config[e]=t,void 0!==fe[e]?fe[e].forEach((function(e){return e()})):n.indexOf(e)>-1&&(w.config[e]=c(t));w.redraw(),be(!0)},w.setDate=function(e,t,n){void 0===t&&(t=!1);void 0===n&&(n=w.config.dateFormat);if(0!==e&&!e||e instanceof Array&&0===e.length)return w.clear(t);me(e,n),w.latestSelectedDateObj=w.selectedDates[w.selectedDates.length-1],w.redraw(),P(void 0,t),_(),0===w.selectedDates.length&&w.clear(!1);be(t),t&&pe("onChange")},w.toggle=function(e){if(!0===w.isOpen)return w.close();w.open(e)};var fe={locale:[le,z],showMonths:[q,k,$],minDate:[P],maxDate:[P],clickOpens:[function(){!0===w.config.clickOpens?(A(w._input,"focus",w.open),A(w._input,"click",w.open)):(w._input.removeEventListener("focus",w.open),w._input.removeEventListener("click",w.open))}]};function me(e,t){var n=[];if(e instanceof Array)n=e.map((function(e){return w.parseDate(e,t)}));else if(e instanceof Date||"number"==typeof e)n=[w.parseDate(e,t)];else if("string"==typeof e)switch(w.config.mode){case"single":case"time":n=[w.parseDate(e,t)];break;case"multiple":n=e.split(w.config.conjunction).map((function(e){return w.parseDate(e,t)}));break;case"range":n=e.split(w.l10n.rangeSeparator).map((function(e){return w.parseDate(e,t)}))}else w.config.errorHandler(new Error("Invalid date supplied: "+JSON.stringify(e)));w.selectedDates=w.config.allowInvalidPreload?n:n.filter((function(e){return e instanceof Date&&X(e,!1)})),"range"===w.config.mode&&w.selectedDates.sort((function(e,t){return e.getTime()-t.getTime()}))}function ge(e){return e.slice().map((function(e){return"string"==typeof e||"number"==typeof e||e instanceof Date?w.parseDate(e,void 0,!0):e&&"object"==typeof e&&e.from&&e.to?{from:w.parseDate(e.from,void 0),to:w.parseDate(e.to,void 0)}:e})).filter((function(e){return e}))}function pe(e,t){if(void 0!==w.config){var n=w.config[e];if(void 0!==n&&n.length>0)for(var a=0;n[a]&&a1||"static"===w.config.monthSelectorType?w.monthElements[t].textContent=h(n.getMonth(),w.config.shorthandCurrentMonth,w.l10n)+" ":w.monthsDropdownContainer.value=n.getMonth().toString(),e.value=n.getFullYear().toString()})),w._hidePrevMonthArrow=void 0!==w.config.minDate&&(w.currentYear===w.config.minDate.getFullYear()?w.currentMonth<=w.config.minDate.getMonth():w.currentYearw.config.maxDate.getMonth():w.currentYear>w.config.maxDate.getFullYear()))}function we(e){return w.selectedDates.map((function(t){return w.formatDate(t,e)})).filter((function(e,t,n){return"range"!==w.config.mode||w.config.enableTime||n.indexOf(e)===t})).join("range"!==w.config.mode?w.config.conjunction:w.l10n.rangeSeparator)}function be(e){void 0===e&&(e=!0),void 0!==w.mobileInput&&w.mobileFormatStr&&(w.mobileInput.value=void 0!==w.latestSelectedDateObj?w.formatDate(w.latestSelectedDateObj,w.mobileFormatStr):""),w.input.value=we(w.config.dateFormat),void 0!==w.altInput&&(w.altInput.value=we(w.config.altFormat)),!1!==e&&pe("onValueUpdate")}function Ce(e){var t=g(e),n=w.prevMonthNav.contains(t),a=w.nextMonthNav.contains(t);n||a?G(n?-1:1):w.yearElements.indexOf(t)>=0?t.select():t.classList.contains("arrowUp")?w.changeYear(w.currentYear+1):t.classList.contains("arrowDown")&&w.changeYear(w.currentYear-1)}return function(){w.element=w.input=p,w.isOpen=!1,function(){var t=["wrap","weekNumbers","allowInput","allowInvalidPreload","clickOpens","time_24hr","enableTime","noCalendar","altInput","shorthandCurrentMonth","inline","static","enableSeconds","disableMobile"],i=e(e({},JSON.parse(JSON.stringify(p.dataset||{}))),v),o={};w.config.parseDate=i.parseDate,w.config.formatDate=i.formatDate,Object.defineProperty(w.config,"enable",{get:function(){return w.config._enable},set:function(e){w.config._enable=ge(e)}}),Object.defineProperty(w.config,"disable",{get:function(){return w.config._disable},set:function(e){w.config._disable=ge(e)}});var r="time"===i.mode;if(!i.dateFormat&&(i.enableTime||r)){var l=T.defaultConfig.dateFormat||a.dateFormat;o.dateFormat=i.noCalendar||r?"H:i"+(i.enableSeconds?":S":""):l+" H:i"+(i.enableSeconds?":S":"")}if(i.altInput&&(i.enableTime||r)&&!i.altFormat){var d=T.defaultConfig.altFormat||a.altFormat;o.altFormat=i.noCalendar||r?"h:i"+(i.enableSeconds?":S K":" K"):d+" h:i"+(i.enableSeconds?":S":"")+" K"}Object.defineProperty(w.config,"minDate",{get:function(){return w.config._minDate},set:oe("min")}),Object.defineProperty(w.config,"maxDate",{get:function(){return w.config._maxDate},set:oe("max")});var s=function(e){return function(t){w.config["min"===e?"_minTime":"_maxTime"]=w.parseDate(t,"H:i:S")}};Object.defineProperty(w.config,"minTime",{get:function(){return w.config._minTime},set:s("min")}),Object.defineProperty(w.config,"maxTime",{get:function(){return w.config._maxTime},set:s("max")}),"time"===i.mode&&(w.config.noCalendar=!0,w.config.enableTime=!0);Object.assign(w.config,o,i);for(var u=0;u-1?w.config[m]=c(f[m]).map(E).concat(w.config[m]):void 0===i[m]&&(w.config[m]=f[m])}i.altInputClass||(w.config.altInputClass=re().className+" "+w.config.altInputClass);pe("onParseConfig")}(),le(),function(){if(w.input=re(),!w.input)return void w.config.errorHandler(new Error("Invalid input element specified"));w.input._type=w.input.type,w.input.type="text",w.input.classList.add("flatpickr-input"),w._input=w.input,w.config.altInput&&(w.altInput=s(w.input.nodeName,w.config.altInputClass),w._input=w.altInput,w.altInput.placeholder=w.input.placeholder,w.altInput.disabled=w.input.disabled,w.altInput.required=w.input.required,w.altInput.tabIndex=w.input.tabIndex,w.altInput.type="text",w.input.setAttribute("type","hidden"),!w.config.static&&w.input.parentNode&&w.input.parentNode.insertBefore(w.altInput,w.input.nextSibling));w.config.allowInput||w._input.setAttribute("readonly","readonly");w._positionElement=w.config.positionElement||w._input}(),function(){w.selectedDates=[],w.now=w.parseDate(w.config.now)||new Date;var e=w.config.defaultDate||("INPUT"!==w.input.nodeName&&"TEXTAREA"!==w.input.nodeName||!w.input.placeholder||w.input.value!==w.input.placeholder?w.input.value:null);e&&me(e,w.config.dateFormat);w._initialDate=w.selectedDates.length>0?w.selectedDates[0]:w.config.minDate&&w.config.minDate.getTime()>w.now.getTime()?w.config.minDate:w.config.maxDate&&w.config.maxDate.getTime()0&&(w.latestSelectedDateObj=w.selectedDates[0]);void 0!==w.config.minTime&&(w.config.minTime=w.parseDate(w.config.minTime,"H:i"));void 0!==w.config.maxTime&&(w.config.maxTime=w.parseDate(w.config.maxTime,"H:i"));w.minDateHasTime=!!w.config.minDate&&(w.config.minDate.getHours()>0||w.config.minDate.getMinutes()>0||w.config.minDate.getSeconds()>0),w.maxDateHasTime=!!w.config.maxDate&&(w.config.maxDate.getHours()>0||w.config.maxDate.getMinutes()>0||w.config.maxDate.getSeconds()>0)}(),w.utils={getDaysInMonth:function(e,t){return void 0===e&&(e=w.currentMonth),void 0===t&&(t=w.currentYear),1===e&&(t%4==0&&t%100!=0||t%400==0)?29:w.l10n.daysInMonth[e]}},w.isMobile||function(){var e=window.document.createDocumentFragment();if(w.calendarContainer=s("div","flatpickr-calendar"),w.calendarContainer.tabIndex=-1,!w.config.noCalendar){if(e.appendChild((w.monthNav=s("div","flatpickr-months"),w.yearElements=[],w.monthElements=[],w.prevMonthNav=s("span","flatpickr-prev-month"),w.prevMonthNav.innerHTML=w.config.prevArrow,w.nextMonthNav=s("span","flatpickr-next-month"),w.nextMonthNav.innerHTML=w.config.nextArrow,q(),Object.defineProperty(w,"_hidePrevMonthArrow",{get:function(){return w.__hidePrevMonthArrow},set:function(e){w.__hidePrevMonthArrow!==e&&(d(w.prevMonthNav,"flatpickr-disabled",e),w.__hidePrevMonthArrow=e)}}),Object.defineProperty(w,"_hideNextMonthArrow",{get:function(){return w.__hideNextMonthArrow},set:function(e){w.__hideNextMonthArrow!==e&&(d(w.nextMonthNav,"flatpickr-disabled",e),w.__hideNextMonthArrow=e)}}),w.currentYearElement=w.yearElements[0],De(),w.monthNav)),w.innerContainer=s("div","flatpickr-innerContainer"),w.config.weekNumbers){var t=function(){w.calendarContainer.classList.add("hasWeeks");var e=s("div","flatpickr-weekwrapper");e.appendChild(s("span","flatpickr-weekday",w.l10n.weekAbbreviation));var t=s("div","flatpickr-weeks");return e.appendChild(t),{weekWrapper:e,weekNumbers:t}}(),n=t.weekWrapper,a=t.weekNumbers;w.innerContainer.appendChild(n),w.weekNumbers=a,w.weekWrapper=n}w.rContainer=s("div","flatpickr-rContainer"),w.rContainer.appendChild($()),w.daysContainer||(w.daysContainer=s("div","flatpickr-days"),w.daysContainer.tabIndex=-1),J(),w.rContainer.appendChild(w.daysContainer),w.innerContainer.appendChild(w.rContainer),e.appendChild(w.innerContainer)}w.config.enableTime&&e.appendChild(function(){w.calendarContainer.classList.add("hasTime"),w.config.noCalendar&&w.calendarContainer.classList.add("noCalendar");var e=x(w.config);w.timeContainer=s("div","flatpickr-time"),w.timeContainer.tabIndex=-1;var t=s("span","flatpickr-time-separator",":"),n=m("flatpickr-hour",{"aria-label":w.l10n.hourAriaLabel});w.hourElement=n.getElementsByTagName("input")[0];var a=m("flatpickr-minute",{"aria-label":w.l10n.minuteAriaLabel});w.minuteElement=a.getElementsByTagName("input")[0],w.hourElement.tabIndex=w.minuteElement.tabIndex=-1,w.hourElement.value=o(w.latestSelectedDateObj?w.latestSelectedDateObj.getHours():w.config.time_24hr?e.hours:function(e){switch(e%24){case 0:case 12:return 12;default:return e%12}}(e.hours)),w.minuteElement.value=o(w.latestSelectedDateObj?w.latestSelectedDateObj.getMinutes():e.minutes),w.hourElement.setAttribute("step",w.config.hourIncrement.toString()),w.minuteElement.setAttribute("step",w.config.minuteIncrement.toString()),w.hourElement.setAttribute("min",w.config.time_24hr?"0":"1"),w.hourElement.setAttribute("max",w.config.time_24hr?"23":"12"),w.hourElement.setAttribute("maxlength","2"),w.minuteElement.setAttribute("min","0"),w.minuteElement.setAttribute("max","59"),w.minuteElement.setAttribute("maxlength","2"),w.timeContainer.appendChild(n),w.timeContainer.appendChild(t),w.timeContainer.appendChild(a),w.config.time_24hr&&w.timeContainer.classList.add("time24hr");if(w.config.enableSeconds){w.timeContainer.classList.add("hasSeconds");var i=m("flatpickr-second");w.secondElement=i.getElementsByTagName("input")[0],w.secondElement.value=o(w.latestSelectedDateObj?w.latestSelectedDateObj.getSeconds():e.seconds),w.secondElement.setAttribute("step",w.minuteElement.getAttribute("step")),w.secondElement.setAttribute("min","0"),w.secondElement.setAttribute("max","59"),w.secondElement.setAttribute("maxlength","2"),w.timeContainer.appendChild(s("span","flatpickr-time-separator",":")),w.timeContainer.appendChild(i)}w.config.time_24hr||(w.amPM=s("span","flatpickr-am-pm",w.l10n.amPM[r((w.latestSelectedDateObj?w.hourElement.value:w.config.defaultHour)>11)]),w.amPM.title=w.l10n.toggleTitle,w.amPM.tabIndex=-1,w.timeContainer.appendChild(w.amPM));return w.timeContainer}());d(w.calendarContainer,"rangeMode","range"===w.config.mode),d(w.calendarContainer,"animate",!0===w.config.animate),d(w.calendarContainer,"multiMonth",w.config.showMonths>1),w.calendarContainer.appendChild(e);var i=void 0!==w.config.appendTo&&void 0!==w.config.appendTo.nodeType;if((w.config.inline||w.config.static)&&(w.calendarContainer.classList.add(w.config.inline?"inline":"static"),w.config.inline&&(!i&&w.element.parentNode?w.element.parentNode.insertBefore(w.calendarContainer,w._input.nextSibling):void 0!==w.config.appendTo&&w.config.appendTo.appendChild(w.calendarContainer)),w.config.static)){var l=s("div","flatpickr-wrapper");w.element.parentNode&&w.element.parentNode.insertBefore(l,w.element),l.appendChild(w.element),w.altInput&&l.appendChild(w.altInput),l.appendChild(w.calendarContainer)}w.config.static||w.config.inline||(void 0!==w.config.appendTo?w.config.appendTo:window.document.body).appendChild(w.calendarContainer)}(),function(){w.config.wrap&&["open","close","toggle","clear"].forEach((function(e){Array.prototype.forEach.call(w.element.querySelectorAll("[data-"+e+"]"),(function(t){return A(t,"click",w[e])}))}));if(w.isMobile)return void function(){var e=w.config.enableTime?w.config.noCalendar?"time":"datetime-local":"date";w.mobileInput=s("input",w.input.className+" flatpickr-mobile"),w.mobileInput.tabIndex=1,w.mobileInput.type=e,w.mobileInput.disabled=w.input.disabled,w.mobileInput.required=w.input.required,w.mobileInput.placeholder=w.input.placeholder,w.mobileFormatStr="datetime-local"===e?"Y-m-d\\TH:i:S":"date"===e?"Y-m-d":"H:i:S",w.selectedDates.length>0&&(w.mobileInput.defaultValue=w.mobileInput.value=w.formatDate(w.selectedDates[0],w.mobileFormatStr));w.config.minDate&&(w.mobileInput.min=w.formatDate(w.config.minDate,"Y-m-d"));w.config.maxDate&&(w.mobileInput.max=w.formatDate(w.config.maxDate,"Y-m-d"));w.input.getAttribute("step")&&(w.mobileInput.step=String(w.input.getAttribute("step")));w.input.type="hidden",void 0!==w.altInput&&(w.altInput.type="hidden");try{w.input.parentNode&&w.input.parentNode.insertBefore(w.mobileInput,w.input.nextSibling)}catch(e){}A(w.mobileInput,"change",(function(e){w.setDate(g(e).value,!1,w.mobileFormatStr),pe("onChange"),pe("onClose")}))}();var e=l(ie,50);w._debouncedChange=l(N,300),w.daysContainer&&!/iPhone|iPad|iPod/i.test(navigator.userAgent)&&A(w.daysContainer,"mouseover",(function(e){"range"===w.config.mode&&ae(g(e))}));A(window.document.body,"keydown",ne),w.config.inline||w.config.static||A(window,"resize",e);void 0!==window.ontouchstart?A(window.document,"touchstart",Z):A(window.document,"mousedown",Z);A(window.document,"focus",Z,{capture:!0}),!0===w.config.clickOpens&&(A(w._input,"focus",w.open),A(w._input,"click",w.open));void 0!==w.daysContainer&&(A(w.monthNav,"click",Ce),A(w.monthNav,["keyup","increment"],F),A(w.daysContainer,"click",ue));if(void 0!==w.timeContainer&&void 0!==w.minuteElement&&void 0!==w.hourElement){var t=function(e){return g(e).select()};A(w.timeContainer,["increment"],I),A(w.timeContainer,"blur",I,{capture:!0}),A(w.timeContainer,"click",Y),A([w.hourElement,w.minuteElement],["focus","click"],t),void 0!==w.secondElement&&A(w.secondElement,"focus",(function(){return w.secondElement&&w.secondElement.select()})),void 0!==w.amPM&&A(w.amPM,"click",(function(e){I(e),N()}))}w.config.allowInput&&A(w._input,"blur",te)}(),(w.selectedDates.length||w.config.noCalendar)&&(w.config.enableTime&&_(w.config.noCalendar?w.latestSelectedDateObj:void 0),be(!1)),k();var t=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);!w.isMobile&&t&&ce(),pe("onReady")}(),w}function k(e,t){for(var n=Array.prototype.slice.call(e).filter((function(e){return e instanceof HTMLElement})),a=[],i=0;i+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 Date: Fri, 19 Mar 2021 09:06:01 +0100 Subject: [PATCH 19/47] typo at fontawesome link, move jquerry out of admin area --- template.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/template.php b/template.php index d8bb071..bf27f2d 100644 --- a/template.php +++ b/template.php @@ -83,7 +83,7 @@ class Template - + + + - From 5e7f0fffac14366edc9d9630d84f0b6ec743e418 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 10:13:23 +0100 Subject: [PATCH 20/47] redesign install.php --- css/main.css | 9 +- install.php | 282 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 186 insertions(+), 105 deletions(-) diff --git a/css/main.css b/css/main.css index 4a21b50..4264129 100644 --- a/css/main.css +++ b/css/main.css @@ -45,6 +45,11 @@ a:focus { margin-right: auto; } +#install .install, +#install form .card:not(:first-child) { + margin-top: 30px; +} + #status-container .input-group:last-child { margin-bottom: 0px !important; } @@ -245,10 +250,6 @@ article.card textarea { padding-bottom: 25px; } -.install .btn { - margin-top: 30px; -} - #footerwrap .dropdown-menu { background: gray; } diff --git a/install.php b/install.php index 55a177a..d458fe4 100644 --- a/install.php +++ b/install.php @@ -169,15 +169,10 @@ if (isset($_POST['server']) && empty($message)) { } } Template::render_header(_("Install")); -?> -

    - - -
    -
    -
    -
    -
    +
    +
    +
    +
    -
    -
    -
    -
    -
    -
    -
    +
    + +

    +

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

    -
    +
    +

    + +

    + + -

    - -

    - - - -
    -
    -

    - https://example.com/status - without the trailing slash), so we can mail users link for forgotten password etc..."); ?> - -
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    - -
    -
    " class="form-control" required>
    -
    -
    - -
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    -
    -
    -

    - - -
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    -
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    -
    -
    -

    - - -
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    -
    -
    " class="form-control" required>
    -
    " class="form-control">
    -
    -
    -
    -
    -
    -
    - - " class="form-control"> + +
    +
    + +
    +
    + https://example.com/status - without the trailing slash), so we can mail users link for forgotten password etc..."); ?> +

    +

    +
    + " class="form-control" required> + +
    +
    + " class="form-control" required> + +
    +
    +
    +
    + " class="form-control" required> + +
    +
    + " class="form-control" required> + +
    +
    +

    +
    -
    -
    -
    -

    - -
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    -
    -
    " class="form-control" required>
    -
    " class="form-control" required>
    -
    -
    -
    " class="form-control" required>
    -
    + +
    +
    + +
    +
    + +

    +

    +
    + " class="form-control" required> + +
    +
    + " class="form-control" required> + +
    +
    +
    +
    + " class="form-control" required> + +
    +
    + " class="form-control" required> + +
    +
    +

    +
    +
    + +
    +
    + +
    +
    + +

    +

    +
    + " class="form-control" required> + +
    +
    + " class="form-control" required> + +
    +
    +
    +
    + " class="form-control" required> + +
    +
    + " class="form-control"> + +
    +
    +
    +
    + + +
    +
    +
    + +
    + " class="form-control"> + +
    +
    +

    +
    +
    + +
    +
    + +
    +
    + +

    +

    +
    + " class="form-control" required> + +
    +
    + " class="form-control" required> + +
    +
    +
    +
    + " class="form-control" required> + +
    +
    + " class="form-control" required> + +
    +
    +
    +
    + " class="form-control" required> + +
    +
    +

    +
    +
    + +
    -
    -
    -
    + +
    +
    Date: Fri, 19 Mar 2021 10:41:08 +0100 Subject: [PATCH 21/47] fix service status colore --- classes/service.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/service.php b/classes/service.php index eb014d2..653f517 100644 --- a/classes/service.php +++ b/classes/service.php @@ -221,7 +221,7 @@ class Service implements JsonSerializable echo '
      '; //echo '
        '; // Render the group status if it exists - echo '
      •  ' . $this->group_name . '
        ' . _($statuses[$this->status]) . '
      • '; + echo '
      •  ' . $this->group_name . '
        ' . _($statuses[$this->status]) . '
      • '; //echo '
      • ' . $this->group_name .'
        status]).'
      • '; $arrCompletedGroups[] = $this->group_name; $boolOpened = true; @@ -241,7 +241,7 @@ class Service implements JsonSerializable if (!empty($this->description)) { echo ' '; } - if ($this->status != -1) { ?>
        status]); ?>
        + if ($this->status != -1) { ?>
        status]); ?>
        '; From 236e1b114512fde33499139a85fd130eb47d05d1 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 11:27:30 +0100 Subject: [PATCH 22/47] unused file --- css/jquery.growl.css | 96 -------------------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 css/jquery.growl.css diff --git a/css/jquery.growl.css b/css/jquery.growl.css deleted file mode 100644 index 18a89dc..0000000 --- a/css/jquery.growl.css +++ /dev/null @@ -1,96 +0,0 @@ -/* jQuery Growl - * Copyright 2015 Kevin Sylvestre - * 1.3.5 - */ -.ontop, #growls-default, #growls-tl, #growls-tr, #growls-bl, #growls-br, #growls-tc, #growls-bc, #growls-cc, #growls-cl, #growls-cr { - z-index: 50000; - position: fixed; } - -#growls-default { - top: 10px; - right: 10px; } -#growls-tl { - top: 10px; - left: 10px; } -#growls-tr { - top: 10px; - right: 10px; } -#growls-bl { - bottom: 10px; - left: 10px; } -#growls-br { - bottom: 10px; - right: 10px; } -#growls-tc { - top: 10px; - right: 10px; - left: 10px; } -#growls-bc { - bottom: 10px; - right: 10px; - left: 10px; } -#growls-cc { - top: 50%; - left: 50%; - margin-left: -125px; } -#growls-cl { - top: 50%; - left: 10px; } -#growls-cr { - top: 50%; - right: 10px; } -#growls-tc .growl, #growls-bc .growl { - margin-left: auto; - margin-right: auto; } - -.growl { - opacity: 0.8; - filter: alpha(opacity=80); - position: relative; - border-radius: 4px; - -webkit-transition: all 0.4s ease-in-out; - -moz-transition: all 0.4s ease-in-out; - transition: all 0.4s ease-in-out; } - .growl.growl-incoming { - opacity: 0; - filter: alpha(opacity=0); } - .growl.growl-outgoing { - opacity: 0; - filter: alpha(opacity=0); } - .growl.growl-small { - width: 200px; - padding: 5px; - margin: 5px; } - .growl.growl-medium { - width: 250px; - padding: 10px; - margin: 10px; } - .growl.growl-large { - width: 300px; - padding: 15px; - margin: 15px; } - .growl.growl-default { - color: #FFF; - background: #7f8c8d; } - .growl.growl-error { - color: #FFF; - background: #C0392B; } - .growl.growl-notice { - color: #FFF; - background: #2ECC71; } - .growl.growl-warning { - color: #FFF; - background: #F39C12; } - .growl .growl-close { - cursor: pointer; - float: right; - font-size: 14px; - line-height: 18px; - font-weight: normal; - font-family: helvetica, verdana, sans-serif; } - .growl .growl-title { - font-size: 18px; - line-height: 24px; } - .growl .growl-message { - font-size: 14px; - line-height: 18px; } From 44f67a28f7ec56a6b6d716105bcf1a1e8f303b27 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 11:27:57 +0100 Subject: [PATCH 23/47] fix policy.php --- policy.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/policy.php b/policy.php index 43dfd01..519d1e6 100644 --- a/policy.php +++ b/policy.php @@ -1,6 +1,11 @@ getSetting($mysqli, "url")); + Template::render_header("Privacy Policy"); echo "

        " . _("Privacy Policy") . "

        "; From dbf76d10f9d716d23f52a9a7d7d04ce8cef97cc3 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 11:33:28 +0100 Subject: [PATCH 24/47] add spaces between Services Groups --- classes/service.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/service.php b/classes/service.php index 653f517..359cdf4 100644 --- a/classes/service.php +++ b/classes/service.php @@ -218,7 +218,7 @@ class Service implements JsonSerializable // If no group exist or group is new, start a new UL if (!empty($this->group_name) && !in_array($this->group_name, $arrCompletedGroups)) { - echo '
          '; + echo '
            '; //echo '
              '; // Render the group status if it exists echo '
            •  ' . $this->group_name . '
              ' . _($statuses[$this->status]) . '
            • '; From 0490a91b709671090320fbbccf56cb64f5cdd72d Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 11:35:11 +0100 Subject: [PATCH 25/47] spacing of services in the dashboard reduced --- admin/dashboard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/dashboard.php b/admin/dashboard.php index f2f0100..4ae5d5c 100644 --- a/admin/dashboard.php +++ b/admin/dashboard.php @@ -52,7 +52,7 @@ Template::render_header(_("Dashboard"), true); foreach ($services as $service) { ?> -
              +
              get_status() != -1) { ?>
              get_id(), $post_services)) ? "checked" : ''; ?> id="service-get_id(); ?>"> From 85f29d89c1c476076b51d725311eb62b30e3df8d Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 12:05:36 +0100 Subject: [PATCH 26/47] redesign options.php --- admin/options.php | 157 ++++++++++++++++++++++++++-------------------- css/main.css | 10 +++ template.php | 4 +- 3 files changed, 102 insertions(+), 69 deletions(-) diff --git a/admin/options.php b/admin/options.php index c557e8b..27f0702 100644 --- a/admin/options.php +++ b/admin/options.php @@ -101,86 +101,109 @@ Template::render_header(_("Options"), true); echo "Server Status Options"; } ?>
              -
              - -
              -
              - Site Name + +
              +
              + +
              +
              +
              +
              + Site Name +
              + +
              -
              - - - -
              -
              - Telegram BOT API Token +
              +
              +
              - -
              -
              -
              - Telegram BOT Username +
              + + + +
              +
              + PHPMailer Path +
              + +
              +
              +
              + PHPMailer SMTP Host +
              + +
              +
              +
              + PHPMailer SMTP Port +
              + +
              +
              +
              + PHPMailer Username +
              + +
              +
              +
              + PHPMailer Password +
              + +
              +
              +
              + Cron Server IP +
              + +
              -
              - - - -
              -
              - PHPMailer Path +
              +
              +
              - -
              -
              -
              - PHPMailer SMTP Host +
              +
              +
              + Telegram BOT API Token +
              + +
              +
              +
              + Telegram BOT Username +
              + +
              - -
              -
              -
              - PHPMailer SMTP Port -
              - -
              -
              -
              - PHPMailer Username -
              - -
              -
              -
              - PHPMailer Password -
              - -
              -
              -
              - Cron Server IP -
              -
              - -
              -
              - Google reChaptcha Sitekey +
              +
              +
              - -
              -
              -
              - Google reChaptcha Secret +
              +
              +
              + Google reChaptcha Sitekey +
              + +
              +
              +
              + Google reChaptcha Secret +
              + +
              -
              - - - +
              + +
              \ No newline at end of file diff --git a/css/main.css b/css/main.css index 4264129..0a9e61e 100644 --- a/css/main.css +++ b/css/main.css @@ -317,6 +317,16 @@ label.form-name { display: inline-block; } /* The switch - the box around the slider */ +#switch { + height: auto; + line-height: 34px; + font-size: 25px; +} + +#switch { + margin-bottom: 5px; +} + .switch { position: relative; display: inline-block; diff --git a/template.php b/template.php index bf27f2d..8adc9cf 100644 --- a/template.php +++ b/template.php @@ -169,14 +169,14 @@ class Template public static function render_toggle($toggletext, $input_name, $checked) { ?> -
              -

              +
              +
              Date: Fri, 19 Mar 2021 12:11:33 +0100 Subject: [PATCH 27/47] lable size unified --- css/main.css | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/css/main.css b/css/main.css index 0a9e61e..fd81a8a 100644 --- a/css/main.css +++ b/css/main.css @@ -292,12 +292,8 @@ body h3 { margin-top: 18px; } -.settings-header { - padding-top: 20px; -} - -.settings-header .float-start h3 { - margin: 0; +#options .input-group-text { + width: 230px; } .row.user .input-group { From a5e154a18c23805e341cad0b0f977e13e3595133 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 12:13:50 +0100 Subject: [PATCH 28/47] typo and hover colore delete services --- admin/settings.php | 2 +- css/main.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/admin/settings.php b/admin/settings.php index 4f2d7e8..1d2fbe0 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -53,7 +53,7 @@ if (isset($message)) { echo "" . $result['group_name'] . ""; if ($user->get_rank() <= 1) { - echo ''; + echo ''; } echo ""; } ?> diff --git a/css/main.css b/css/main.css index fd81a8a..25b5158 100644 --- a/css/main.css +++ b/css/main.css @@ -242,6 +242,10 @@ article.card textarea { font-size: 1em; } +.delete-service:hover { + color: darkred; +} + .service label { margin-bottom: 0; } From ba17ae386341f3806431aaf08bbbd74ba4a64421 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 12:34:46 +0100 Subject: [PATCH 29/47] use bootstrap for delete link --- admin/settings.php | 4 ++-- css/main.css | 9 --------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/admin/settings.php b/admin/settings.php index 1d2fbe0..97c3cd9 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -53,7 +53,7 @@ if (isset($message)) { echo "" . $result['group_name'] . ""; if ($user->get_rank() <= 1) { - echo ''; + echo ''; } echo ""; } ?> @@ -102,7 +102,7 @@ if (isset($message)) { echo "" . $visibility[$result['visibility']] . ""; if ($user->get_rank() <= 1) { - echo ''; + echo ''; } echo ""; } ?> diff --git a/css/main.css b/css/main.css index 25b5158..4923348 100644 --- a/css/main.css +++ b/css/main.css @@ -237,15 +237,6 @@ article.card textarea { min-width: 250px; } -.delete-service { - color: red; - font-size: 1em; -} - -.delete-service:hover { - color: darkred; -} - .service label { margin-bottom: 0; } From 421a0d23d31cd6f04badff5bed595b934b73f7f4 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 14:39:59 +0100 Subject: [PATCH 30/47] Cleanup --- css/main.css | 9 +--- template.php | 115 ++++++++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 69 deletions(-) diff --git a/css/main.css b/css/main.css index 4923348..9bec61d 100644 --- a/css/main.css +++ b/css/main.css @@ -1,6 +1,3 @@ -@import url("https://fonts.googleapis.com/css?family=Open+Sans:400&subset=cyrillic,cyrillic-ext,greek,greek-ext,latin-ext,vietnamese"); -@import url("https://fonts.googleapis.com/css?family=Fira+Sans:400,700&subset=cyrillic,cyrillic-ext,greek,greek-ext,latin-ext,vietnamese"); - body { background: #ffffff; margin: 0; @@ -36,7 +33,7 @@ a:focus { border-radius: 0px 0px 30px 30px; } -#wrapper { +main.container { max-width: 1024px; min-height: calc(100vh - 157px); padding-right: 15px; @@ -210,7 +207,7 @@ article.card textarea { margin-left: 70px; } -#wrapper.admin #timeline .service input[type="checkbox"] { +main.container.admin #timeline .service input[type="checkbox"] { margin-right: 4px; margin-top: 0; vertical-align: middle; @@ -254,8 +251,6 @@ article.card textarea { width: 100%; padding: 2px 5px; display: block; - transition: 125ms ease-in-out background-color; - background-color: gray; } #footerwrap .dropdown-menu a:hover { diff --git a/template.php b/template.php index 8adc9cf..57c1ab5 100644 --- a/template.php +++ b/template.php @@ -145,19 +145,10 @@ class Template
              - -
              - -
              - admin"> + - -
              - - -
              - + + +
              + get_accepted_langs(); - ?> - - + + + + + + + + + From c63c21212b413bf60e6ebfd2b04fbe2de2bcbfe3 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 14:41:41 +0100 Subject: [PATCH 31/47] group headline colore --- classes/service.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/service.php b/classes/service.php index 359cdf4..4b45bc9 100644 --- a/classes/service.php +++ b/classes/service.php @@ -221,7 +221,7 @@ class Service implements JsonSerializable echo '
                '; //echo '
                  '; // Render the group status if it exists - echo '
                •  ' . $this->group_name . '
                  ' . _($statuses[$this->status]) . '
                • '; + echo '
                •  ' . $this->group_name . '
                  ' . _($statuses[$this->status]) . '
                • '; //echo '
                • ' . $this->group_name .'
                  status]).'
                • '; $arrCompletedGroups[] = $this->group_name; $boolOpened = true; From 1c414ea4287e1c0437fa33950a31615cf61b9b16 Mon Sep 17 00:00:00 2001 From: Tealk Date: Fri, 19 Mar 2021 19:38:54 +0100 Subject: [PATCH 32/47] variable id inserted, css recreated(sass) --- 404.php | 2 +- admin/dashboard.php | 2 +- admin/login-form.php | 4 +- admin/lost-password.php | 2 +- admin/new-user.php | 2 +- admin/options.php | 2 +- admin/service-group.php | 4 +- admin/service.php | 4 +- admin/settings.php | 2 +- admin/user.php | 2 +- classes/service.php | 4 +- css/main.css | 377 +--------------------------------------- css/main.css.map | 1 + css/main.sass | 277 +++++++++++++++++++++++++++++ email_subscriptions.php | 8 +- index.php | 2 +- install.php | 6 +- policy.php | 2 +- subscriptions.php | 2 +- template.php | 4 +- 20 files changed, 306 insertions(+), 403 deletions(-) create mode 100644 css/main.css.map create mode 100644 css/main.sass diff --git a/404.php b/404.php index 4da48e2..22a2165 100644 --- a/404.php +++ b/404.php @@ -5,7 +5,7 @@ if (!file_exists("config.php")) { } else { require_once("config.php"); - Template::render_header("Page not found"); + Template::render_header("Page not found", "notfound"); ?>

                  diff --git a/admin/dashboard.php b/admin/dashboard.php index 4ae5d5c..7b32733 100644 --- a/admin/dashboard.php +++ b/admin/dashboard.php @@ -18,7 +18,7 @@ if (isset($_GET['tasks'])) { Queue::process_queue(); } -Template::render_header(_("Dashboard"), true); +Template::render_header(_("Dashboard"), "dashboard", true); ?>
                  diff --git a/admin/login-form.php b/admin/login-form.php index c412114..b166bae 100644 --- a/admin/login-form.php +++ b/admin/login-form.php @@ -1,10 +1,10 @@

                  -
                  +

                  diff --git a/admin/lost-password.php b/admin/lost-password.php index c9cfe2a..2fb6ebd 100644 --- a/admin/lost-password.php +++ b/admin/lost-password.php @@ -1,5 +1,5 @@

                  diff --git a/admin/new-user.php b/admin/new-user.php index 54ce434..87766c5 100644 --- a/admin/new-user.php +++ b/admin/new-user.php @@ -3,7 +3,7 @@ if (isset($_GET['new'])) { User::add(); } -Template::render_header(_("New user"), true); ?> +Template::render_header(_("New user"), "newuser", true); ?>

                  Add new user

                  diff --git a/admin/options.php b/admin/options.php index 27f0702..45699de 100644 --- a/admin/options.php +++ b/admin/options.php @@ -92,7 +92,7 @@ if (!empty($_POST)) { define("CRON_SERVER_IP", $db->getSetting($mysqli,"cron_server_ip")); */ } -Template::render_header(_("Options"), true); +Template::render_header(_("Options"), "options", true); ?>

                  + Template::render_header(_("New service group"), "servicegroup", true); ?>

                  + Template::render_header(_("Edit service group"), "servicegroup", true); ?>

                  diff --git a/admin/service.php b/admin/service.php index 8c07488..9c68e96 100644 --- a/admin/service.php +++ b/admin/service.php @@ -34,14 +34,14 @@ if (isset($_GET['id']) && !isset($_POST['id'])) { if (!$boolEdit) { - Template::render_header(_("New service"), true); ?> + Template::render_header(_("New service"), "service", true); ?>

                  + Template::render_header(_("New service"), "service", true); ?>

                  diff --git a/admin/settings.php b/admin/settings.php index 97c3cd9..f54ff79 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -7,7 +7,7 @@ if (isset($_GET['delete']) && isset($_GET['type'])) { } } -Template::render_header(_("Settings"), true); +Template::render_header(_("Settings"), "settings", true); ?>

                  Settings

                  diff --git a/admin/user.php b/admin/user.php index 218d2e5..94bdced 100644 --- a/admin/user.php +++ b/admin/user.php @@ -35,7 +35,7 @@ if (isset($_GET['what']) && $_GET['what'] == 'toggle') { $displayed_user->toggle(); } -Template::render_header(_("User"), true); +Template::render_header(_("User"), "user", true); ?>
                  diff --git a/classes/service.php b/classes/service.php index 4b45bc9..77d12b3 100644 --- a/classes/service.php +++ b/classes/service.php @@ -221,7 +221,7 @@ class Service implements JsonSerializable echo '
                    '; //echo '
                      '; // Render the group status if it exists - echo '
                    •  ' . $this->group_name . '
                      ' . _($statuses[$this->status]) . '
                    • '; + echo '
                    •  ' . $this->group_name . '
                      ' . _($statuses[$this->status]) . '
                    • '; //echo '
                    • ' . $this->group_name .'
                      status]).'
                    • '; $arrCompletedGroups[] = $this->group_name; $boolOpened = true; @@ -241,7 +241,7 @@ class Service implements JsonSerializable if (!empty($this->description)) { echo ' '; } - if ($this->status != -1) { ?>
                      status]); ?>
                      + if ($this->status != -1) { ?>
                      status]); ?>
                      '; diff --git a/css/main.css b/css/main.css index 9bec61d..8a9725e 100644 --- a/css/main.css +++ b/css/main.css @@ -1,376 +1 @@ -body { - background: #ffffff; - margin: 0; - margin-top: 80px; - height: 100%; - line-height: 24px; - font-family: "Open Sans", sans-serif; -} - -img { - height: auto; - max-width: 100%; -} - -a { - padding: 0; - margin: 0; - text-decoration: none; -} - -a:hover, -a:focus { - text-decoration: none; - color: #f5f4f4; -} - -.centered { - text-align: center; -} - -.navbar { - background-color: gray; - border-radius: 0px 0px 30px 30px; -} - -main.container { - max-width: 1024px; - min-height: calc(100vh - 157px); - padding-right: 15px; - padding-left: 15px; - margin-left: auto; - margin-right: auto; -} - -#install .install, -#install form .card:not(:first-child) { - margin-top: 30px; -} - -#status-container .input-group:last-child { - margin-bottom: 0px !important; -} - -.status { - float: right; - font-size: 1.05em; -} - -#status-big { - margin-bottom: 20px; - padding: 15px; - border-radius: 5px; - font-size: 1.3em; -} - -.timeline { - position: relative; - padding: 0 0px 10px; - margin-top: 4px; -} - -.timeline .line { - position: absolute; - width: 2px; - display: block; - background: #c2c2c2; - top: 0px; - bottom: 0px; - margin-left: 31px; -} - -.timeline .servicelist { - position: relative; - margin: 10px 0px 21px 70px; - clear: both; -} - -.timeline .card { - position: relative; - margin: 10px 0px 21px 70px; - clear: both; -} - -.timeline .card::before { - position: absolute; - display: block; - top: 8px; - left: -24px; - content: ""; - width: 0px; - height: 0px; - border: inherit; - border-width: 12px; - border-top-color: transparent; - border-bottom-color: transparent; - border-left-color: transparent; -} - -.timeline .card .card-colore.icon * { - /*This shouldn't be relative in size...*/ - font-size: 20px; - vertical-align: middle; - line-height: 40px; -} -.timeline .card .card-colore.icon { - position: absolute; - left: -59px; - display: block; - width: 40px; - height: 40px; - padding: 0px; - border-radius: 50%; - text-align: center; - float: left; -} - -.timeline .card-outline { - border-color: transparent; - background: transparent; - box-shadow: none; -} - -.timeline .card-outline .panel-body { - padding: 10px 0px; -} - -.timeline .line::before { - top: -4px; -} - -.timeline .line::before { - content: ""; - position: absolute; - left: -4px; - width: 10px; - height: 10px; - display: block; - border-radius: 50%; - background: #c2c2c2; -} - -/* Footer */ -#footerwrap { - border-radius: 30px 30px 0px 0px; - min-height: 60px; - padding-top: 15px; - padding-bottom: 10px; - background: gray; -} - -#timeline h3 { - margin-top: 40px; - padding-left: 70px; -} - -#login-form { - padding-top: 20px; -} - -#time input { - max-width: 100%; -} - -.card.border-primary input#title { - width: 80%; -} - -.card:not(.border-primary) input#title { - width: 100%; -} - -.card:not(.border-primary) #time, -.card:not(.border-primary) #end_time_wrapper { - display: none; -} - -#time::-moz-placeholder, -#title::-moz-placeholder { - opacity: 1; -} - -article.card input { - background: transparent; - border: none; - border-bottom: 1px white outset; -} - -article.card textarea { - width: 100%; - background: transparent; - border: none; - resize: vertical; - min-height: 100px; -} - -#type { - margin-left: 70px; -} - -main.container.admin #timeline .service input[type="checkbox"] { - margin-right: 4px; - margin-top: 0; - vertical-align: middle; -} - -#status-container.error input { - box-shadow: 0px 0 2px 1px rgba(255, 0, 0, 1); -} - -.delete { - margin-left: 5px; - font-size: 1.2em; - color: white; - line-height: 25px; -} - -.delete:hover, -.delete:focus { - color: #eee; -} - -.new-service { - width: 100%; - min-width: 250px; -} - -.service label { - margin-bottom: 0; -} - -.install { - padding-bottom: 25px; -} - -#footerwrap .dropdown-menu { - background: gray; -} - -#footerwrap .dropdown-menu a { - color: white; - width: 100%; - padding: 2px 5px; - display: block; -} - -#footerwrap .dropdown-menu a:hover { - background-color: #2f8ad8; -} - -#footerwrap .input-group.dropup.mb-3 { - display: block; -} - -#footerwrap .input-group.dropup.mb-3 img { - max-height: 20px; - max-width: 25px; - margin-right: 5px; - vertical-align: middle; -} - -.col-md-4.text-left, -.col-md-4.text-right { - line-height: 2.5; -} - -body .h1, -body .h2, -body .h3, -body h1, -body h2, -body h3 { - margin-top: 18px; -} - -#options .input-group-text { - width: 230px; -} - -.row.user .input-group { - width: 100%; - margin-bottom: 5px; -} - -.row.user .form-name { - width: 50%; - float: left; -} - -label.form-name { - line-height: 20px; -} -.panel .panel-footer .label { - display: inline-block; -} -/* The switch - the box around the slider */ -#switch { - height: auto; - line-height: 34px; - font-size: 25px; -} - -#switch { - margin-bottom: 5px; -} - -.switch { - position: relative; - display: inline-block; - width: 60px; - height: 34px; -} - -/* Hide default HTML checkbox */ -.switch input { - opacity: 0; - width: 0; - height: 0; -} - -/* The slider */ -.slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #ccc; - -webkit-transition: 0.4s; - transition: 0.4s; -} - -.slider:before { - position: absolute; - content: ""; - height: 26px; - width: 26px; - left: 4px; - bottom: 4px; - background-color: white; - -webkit-transition: 0.4s; - transition: 0.4s; -} - -input:checked + .slider { - background-color: #2196f3; -} - -input:focus + .slider { - box-shadow: 0 0 1px #2196f3; -} - -input:checked + .slider:before { - -webkit-transform: translateX(26px); - -ms-transform: translateX(26px); - transform: translateX(26px); -} - -/* Rounded sliders */ -.slider.round { - border-radius: 34px; -} - -.slider.round:before { - border-radius: 50%; -} +body{background:#fff;margin:0;margin-top:80px;height:100%;line-height:24px;font-family:"Open Sans",sans-serif}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header.navbar{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/css/main.css.map b/css/main.css.map new file mode 100644 index 0000000..9557cc8 --- /dev/null +++ b/css/main.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KACE,eAAA,CACA,QAAA,CACA,eAAA,CACA,WAAA,CACA,gBAAA,CACA,kCAAA,CAEA,mDACE,eAAA,CAEJ,IACE,WAAA,CACA,cAAA,CAEF,EACE,SAAA,CACA,QAAA,CACA,oBAAA,CAEA,gBACE,oBAAA,CACA,aAAA,CAEJ,UACE,iBAAA,CAEF,QACE,WAAA,CACA,gBAAA,CACA,cAAA,CACA,iBAAA,CAEA,gBACE,iBAAA,CACA,oBAAA,CACA,UAAA,CACA,WAAA,CAEA,sBACE,SAAA,CACA,OAAA,CACA,QAAA,CAEF,wBACE,iBAAA,CACA,cAAA,CACA,KAAA,CACA,MAAA,CACA,OAAA,CACA,QAAA,CACA,qBAAA,CAEA,cAAA,CAEA,+BACE,iBAAA,CACA,UAAA,CACA,WAAA,CACA,UAAA,CACA,QAAA,CACA,UAAA,CACA,qBAAA,CAEA,cAAA,CAEF,8BACE,kBAAA,CAEA,qCACE,iBAAA,CAGN,8BACE,wBAAA,CAEF,4BACE,0BAAA,CAEF,qCACE,0BAAA,CAEN,cACI,qBAAA,CACA,+BAAA,CAEJ,eACE,gBAAA,CACA,8BAAA,CACA,kBAAA,CACA,iBAAA,CACA,gBAAA,CACA,iBAAA,CAIE,iCACE,mBAAA,CAEF,qFAEE,eAAA,CAKF,uEACE,kBAAA,CACA,YAAA,CACA,iBAAA,CACA,eAAA,CAEF,mEACE,iBAAA,CACA,kBAAA,CACA,cAAA,CAEA,yEACE,eAAA,CACA,iBAAA,CAEF,+EACE,iBAAA,CACA,SAAA,CACA,aAAA,CACA,kBAAA,CACA,OAAA,CACA,UAAA,CACA,gBAAA,CAEA,+FACE,QAAA,CACA,SAAA,CACA,UAAA,CACA,iBAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,kBAAA,CAEJ,6FACE,iBAAA,CACA,yBAAA,CACA,UAAA,CAEF,+EACE,yBAAA,CAEA,+FACE,iBAAA,CACA,OAAA,CACA,UAAA,CACA,UAAA,CACA,cAAA,CACA,iBAAA,CACA,4BAAA,CACA,+BAAA,CACA,6BAAA,CAEF,mHACE,iBAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,iBAAA,CAEA,uHACE,cAAA,CACA,gBAAA,CAEV,sBACE,gBAAA,CAYA,iCACE,WAAA,CACA,gBAAA,CAEF,uDACI,SAAA,CAIF,uEACE,UAAA,CAEF,8IAEE,YAAA,CAIF,4CACE,sBAAA,CACA,WAAA,CACA,6BAAA,CAEF,+CACE,UAAA,CACA,sBAAA,CACA,WAAA,CACA,eAAA,CACA,gBAAA,CAEF,8CACE,eAAA,CACA,eAAA,CACA,UAAA,CACA,gBAAA,CAEA,wGACE,UAAA,CAEN,+BACE,gBAAA,CAEF,uDACE,4BAAA,CAIF,8BACE,gBAAA,CAYF,0CACE,WAAA,CAKN,kBACE,+BAAA,CACA,eAAA,CACA,gBAAA,CACA,mBAAA,CACA,eAAA,CAEA,iCACE,eAAA,CAEA,mCACE,UAAA,CACA,UAAA,CACA,eAAA,CACA,aAAA,CAEA,yCACE,wBAAA,CAEN,2CACE,aAAA,CAEA,+CACE,eAAA,CACA,cAAA,CACA,gBAAA,CACA,qBAAA","file":"main.css"} \ No newline at end of file diff --git a/css/main.sass b/css/main.sass new file mode 100644 index 0000000..8581bd1 --- /dev/null +++ b/css/main.sass @@ -0,0 +1,277 @@ +body + background: #ffffff + margin: 0 + margin-top: 80px + height: 100% + line-height: 24px + font-family: "Open Sans", sans-serif + + .h1, .h2, .h3, h1, h2, h3 + margin-top: 18px + +img + height: auto + max-width: 100% + +a + padding: 0 + margin: 0 + text-decoration: none + + &:hover, &:focus + text-decoration: none + color: #f5f4f4 + +.centered + text-align: center + +#switch + height: auto + line-height: 34px + font-size: 25px + margin-bottom: 5px + + .switch + position: relative + display: inline-block + width: 60px + height: 34px + + input + opacity: 0 + width: 0 + height: 0 + + .slider + position: absolute + cursor: pointer + top: 0 + left: 0 + right: 0 + bottom: 0 + background-color: #ccc + -webkit-transition: 0.4s + transition: 0.4s + + &:before + position: absolute + content: "" + height: 26px + width: 26px + left: 4px + bottom: 4px + background-color: white + -webkit-transition: 0.4s + transition: 0.4s + + &.round + border-radius: 34px + + &:before + border-radius: 50% + + input + &:checked + .slider + background-color: #2196f3 + + &:focus + .slider + box-shadow: 0 0 1px #2196f3 + + &:checked + .slider:before + transform: translateX(26px) + +header.navbar + background-color: gray + border-radius: 0px 0px 30px 30px + +main.container + max-width: 1024px + min-height: calc(100vh - 157px) + padding-right: 15px + padding-left: 15px + margin-left: auto + margin-right: auto + + &#install + + .settings + padding-bottom: 25px + + .settings, + form .card:not(:first-child) + margin-top: 30px + + &#status, + &#dashboard + + #status-big + margin-bottom: 20px + padding: 15px + border-radius: 5px + font-size: 1.3em + + .timeline + position: relative + padding: 0 0px 10px + margin-top: 4px + + h3 + margin-top: 40px + padding-left: 70px + + .line + position: absolute + width: 2px + display: block + background: #c2c2c2 + top: 0px + bottom: 0px + margin-left: 31px + + &::before + top: -4px + left: -4px + content: "" + position: absolute + width: 10px + height: 10px + border-radius: 50% + background: #c2c2c2 + + .servicelist + position: relative + margin: 10px 0px 21px 70px + clear: both + + .card + margin: 10px 0px 21px 70px + + &::before + position: absolute + top: 8px + left: -24px + content: "" + border: inherit + border-width: 12px + border-top-color: transparent + border-bottom-color: transparent + border-left-color: transparent + + .card-colore.icon + position: absolute + left: -59px + width: 40px + height: 40px + border-radius: 50% + text-align: center + + i + font-size: 20px + line-height: 40px + + &#status + font-size: 1.05em + + &#notfound + + &#privacy + + &#subscripe + + &#subsmail + + &#dashboard + + #status + width: 230px + text-align: right + + .card-header.bg-primary input + width: 80% + + .card-header:not(.border-primary) + + input#title + width: 100% + + #time, + #end_time_wrapper + display: none + + article.card + + input + background: transparent + border: none + border-bottom: 1px white outset + + textarea + width: 100% + background: transparent + border: none + resize: vertical + min-height: 100px + + .delete + margin-left: 5px + font-size: 1.2em + color: white + line-height: 25px + + &:hover, &:focus + color: #eee + + #type + margin-left: 70px + + #status-container.error input + box-shadow: 0px 0 2px 1px rgba(255, 0, 0, 1) + + &#login + + .wrapper + padding-top: 20px + + &#lostpw + + &#newuser + + &#servicegroup + + &#service + + &#settings + + .input-group-text + width: 230px + + #user + + +footer#footerwrap + border-radius: 30px 30px 0px 0px + min-height: 60px + padding-top: 15px + padding-bottom: 10px + background: gray + + .dropdown-menu + background: gray + + a + color: white + width: 100% + padding: 2px 5px + display: block + + &:hover + background-color: #2f8ad8 + + .input-group.dropup.mb-3 + display: block + + img + max-height: 20px + max-width: 25px + margin-right: 5px + vertical-align: middle \ No newline at end of file diff --git a/email_subscriptions.php b/email_subscriptions.php index a06a29d..ef9c081 100644 --- a/email_subscriptions.php +++ b/email_subscriptions.php @@ -41,7 +41,7 @@ if (isset($_GET['new'])) { // Form validation for subscribers signing up $message = ""; - Template::render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription"), "subsmail"); if (isset($_POST['emailaddress'])) { @@ -172,7 +172,7 @@ if (isset($_GET['new'])) { header('Location: subscriptions.php'); exit; } else { - Template::render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription"), "subsmail"); $header = _("We cannot find a valid subscriber account matching those details"); $message = _("If you have recently subscribed, please make sure you activate the account within two hours of doing so. You are welcome to try and re-subscribe."); @@ -187,7 +187,7 @@ if (isset($_GET['new'])) { if ($subscriber->get_subscriber_by_token($_GET['token'])) { $subscriber->delete($subscriber->id); $subscriber->set_logged_off(); - Template::render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription"), "subsmail"); $header = _("You have been unsubscribed from our system"); $message = _("We are sorry to see you go. If you want to subscribe again at a later date please feel free to re-subscribe."); @@ -195,7 +195,7 @@ if (isset($_GET['new'])) { } else { // TODO Log token for troubleshooting ? // Cannot find subscriber - show alert - Template::render_header(_("Email Subscription")); + Template::render_header(_("Email Subscription"), "subsmail"); $header = _("We are unable to find any valid subscriber detail matching your submitted data!"); $message = _("If you believe this to be an error, please contact the system admininistrator."); $constellation->render_warning($header, $message, true, WEB_URL, _('Go back')); diff --git a/index.php b/index.php index 18126a1..b81cf19 100644 --- a/index.php +++ b/index.php @@ -88,7 +88,7 @@ if($db->getSetting($mysqli,"notifyUpdates") == "yes"){ } } */ - Template::render_header("Status"); + Template::render_header("Status", "status"); ?>

                      diff --git a/install.php b/install.php index d458fe4..69838ad 100644 --- a/install.php +++ b/install.php @@ -168,7 +168,7 @@ if (isset($_POST['server']) && empty($message)) { header("Location: " . WEB_URL); } } -Template::render_header(_("Install")); +Template::render_header(_("Install"), "install"); $php_version_req = sprintf(_("Minimum PHP version %s"), MINIMUM_PHP_VERSION); $preq_fail = array("times", "danger"); @@ -197,7 +197,7 @@ if (is_writable(__DIR__)) { } ?> -
                      +
                      @@ -223,7 +223,7 @@ if (is_writable(__DIR__)) {
                      -
                      +

                      getSetting($mysqli, "url")); -Template::render_header("Privacy Policy"); +Template::render_header("Privacy Policy", "privacy"); echo "

                      " . _("Privacy Policy") . "

                      "; echo "

                      " . _("Who we are") . "

                      "; diff --git a/subscriptions.php b/subscriptions.php index fea6dbf..c38d975 100644 --- a/subscriptions.php +++ b/subscriptions.php @@ -22,7 +22,7 @@ define("TG_BOT_USERNAME", $db->getSetting($mysqli, "tg_bot_username")); $subscription = new Subscriptions(); $telegram = new Telegram(); -Template::render_header("Subscriptions"); +Template::render_header("Subscriptions", "subscripe"); if (SUBSCRIBE_TELEGRAM && $_SESSION['subscriber_typeid'] == 2) { $tg_user = $telegram->getTelegramUserData(); // TODO: Do we need this any longer? diff --git a/template.php b/template.php index 57c1ab5..f41f30b 100644 --- a/template.php +++ b/template.php @@ -17,7 +17,7 @@ class Template * @param String $page_name name of the page to be displayed as title * @param Boolean $admin decides whether to show admin menu */ - public static function render_header($page_name, $admin = false) + public static function render_header($page_name, $page_id, $admin = false) { if (!$admin) { // Create subscriber menu sections for later inclusion @@ -145,7 +145,7 @@ class Template
                      -
                      +
                      Date: Fri, 19 Mar 2021 21:03:57 +0100 Subject: [PATCH 33/47] color value for links --- template.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/template.php b/template.php index f41f30b..ba6f912 100644 --- a/template.php +++ b/template.php @@ -124,19 +124,22 @@ class Template global $user; ?> + Date: Fri, 19 Mar 2021 21:27:10 +0100 Subject: [PATCH 34/47] remove test button --- template.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/template.php b/template.php index ba6f912..5f58994 100644 --- a/template.php +++ b/template.php @@ -138,9 +138,6 @@ class Template - From 6cecff3cc36bf193ab4b205fe0c6d0ca2c2131a5 Mon Sep 17 00:00:00 2001 From: Tealk Date: Sat, 20 Mar 2021 13:08:49 +0100 Subject: [PATCH 35/47] add darkmode switch --- css/main.css | 2 +- css/main.css.map | 2 +- css/main.sass | 37 ++++++++++++++++++++++++++++++++++--- js/main.js | 26 ++++++++++++++++++++++++++ template.php | 12 ++++++++++-- 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/css/main.css b/css/main.css index 8a9725e..eac1472 100644 --- a/css/main.css +++ b/css/main.css @@ -1 +1 @@ -body{background:#fff;margin:0;margin-top:80px;height:100%;line-height:24px;font-family:"Open Sans",sans-serif}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header.navbar{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}/*# sourceMappingURL=main.css.map */ \ No newline at end of file +body{background-color:#fff;color:#111;margin:0;margin-top:80px;height:100%;line-height:24px;font-family:"Open Sans",sans-serif}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}body[data-theme=dark]{background-color:#111}body[data-theme=dark] main{color:#fff}body[data-theme=dark] .fa-moon::before{content:""}body[data-theme=dark] .list-group-item{border-color:rgba(255,255,255,.125)}body[data-theme=dark] .list-group-item.sub-component{background-color:#111;color:#fff}body[data-theme=dark] .card{background-color:#111;color:#fff;border-color:rgba(255,255,255,.125)}body[data-theme=dark] .table{color:#fff}/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/css/main.css.map b/css/main.css.map index 9557cc8..69cbefc 100644 --- a/css/main.css.map +++ b/css/main.css.map @@ -1 +1 @@ -{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KACE,eAAA,CACA,QAAA,CACA,eAAA,CACA,WAAA,CACA,gBAAA,CACA,kCAAA,CAEA,mDACE,eAAA,CAEJ,IACE,WAAA,CACA,cAAA,CAEF,EACE,SAAA,CACA,QAAA,CACA,oBAAA,CAEA,gBACE,oBAAA,CACA,aAAA,CAEJ,UACE,iBAAA,CAEF,QACE,WAAA,CACA,gBAAA,CACA,cAAA,CACA,iBAAA,CAEA,gBACE,iBAAA,CACA,oBAAA,CACA,UAAA,CACA,WAAA,CAEA,sBACE,SAAA,CACA,OAAA,CACA,QAAA,CAEF,wBACE,iBAAA,CACA,cAAA,CACA,KAAA,CACA,MAAA,CACA,OAAA,CACA,QAAA,CACA,qBAAA,CAEA,cAAA,CAEA,+BACE,iBAAA,CACA,UAAA,CACA,WAAA,CACA,UAAA,CACA,QAAA,CACA,UAAA,CACA,qBAAA,CAEA,cAAA,CAEF,8BACE,kBAAA,CAEA,qCACE,iBAAA,CAGN,8BACE,wBAAA,CAEF,4BACE,0BAAA,CAEF,qCACE,0BAAA,CAEN,cACI,qBAAA,CACA,+BAAA,CAEJ,eACE,gBAAA,CACA,8BAAA,CACA,kBAAA,CACA,iBAAA,CACA,gBAAA,CACA,iBAAA,CAIE,iCACE,mBAAA,CAEF,qFAEE,eAAA,CAKF,uEACE,kBAAA,CACA,YAAA,CACA,iBAAA,CACA,eAAA,CAEF,mEACE,iBAAA,CACA,kBAAA,CACA,cAAA,CAEA,yEACE,eAAA,CACA,iBAAA,CAEF,+EACE,iBAAA,CACA,SAAA,CACA,aAAA,CACA,kBAAA,CACA,OAAA,CACA,UAAA,CACA,gBAAA,CAEA,+FACE,QAAA,CACA,SAAA,CACA,UAAA,CACA,iBAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,kBAAA,CAEJ,6FACE,iBAAA,CACA,yBAAA,CACA,UAAA,CAEF,+EACE,yBAAA,CAEA,+FACE,iBAAA,CACA,OAAA,CACA,UAAA,CACA,UAAA,CACA,cAAA,CACA,iBAAA,CACA,4BAAA,CACA,+BAAA,CACA,6BAAA,CAEF,mHACE,iBAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,iBAAA,CAEA,uHACE,cAAA,CACA,gBAAA,CAEV,sBACE,gBAAA,CAYA,iCACE,WAAA,CACA,gBAAA,CAEF,uDACI,SAAA,CAIF,uEACE,UAAA,CAEF,8IAEE,YAAA,CAIF,4CACE,sBAAA,CACA,WAAA,CACA,6BAAA,CAEF,+CACE,UAAA,CACA,sBAAA,CACA,WAAA,CACA,eAAA,CACA,gBAAA,CAEF,8CACE,eAAA,CACA,eAAA,CACA,UAAA,CACA,gBAAA,CAEA,wGACE,UAAA,CAEN,+BACE,gBAAA,CAEF,uDACE,4BAAA,CAIF,8BACE,gBAAA,CAYF,0CACE,WAAA,CAKN,kBACE,+BAAA,CACA,eAAA,CACA,gBAAA,CACA,mBAAA,CACA,eAAA,CAEA,iCACE,eAAA,CAEA,mCACE,UAAA,CACA,UAAA,CACA,eAAA,CACA,aAAA,CAEA,yCACE,wBAAA,CAEN,2CACE,aAAA,CAEA,+CACE,eAAA,CACA,cAAA,CACA,gBAAA,CACA,qBAAA","file":"main.css"} \ No newline at end of file +{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KAMA,qBANW,CAAA,UACE,CAAA,QAQX,CAAA,eACA,CAAA,WACA,CAAA,gBACA,CAAA,kCACA,CAAA,mDAEA,eACE,CAAA,IAEJ,WACE,CAAA,cACA,CAAA,EAEF,SACE,CAAA,QACA,CAAA,oBACA,CAAA,gBAEA,oBACE,CAAA,aACA,CAAA,UAEJ,iBACE,CAAA,QAEF,WACE,CAAA,gBACA,CAAA,cACA,CAAA,iBACA,CAAA,gBAEA,iBACE,CAAA,oBACA,CAAA,UACA,CAAA,WACA,CAAA,sBAEA,SACE,CAAA,OACA,CAAA,QACA,CAAA,wBAEF,iBACE,CAAA,cACA,CAAA,KACA,CAAA,MACA,CAAA,OACA,CAAA,QACA,CAAA,qBACA,CACA,cACA,CAAA,+BAEA,iBACE,CAAA,UACA,CAAA,WACA,CAAA,UACA,CAAA,QACA,CAAA,UACA,CAAA,qBACA,CACA,cACA,CAAA,8BAEF,kBACE,CAAA,qCAEA,iBACE,CAAA,8BAGN,wBACE,CAAA,4BAEF,0BACE,CAAA,qCAEF,0BACE,CAAA,OAEN,qBACI,CAAA,+BACA,CAAA,eAEJ,gBACE,CAAA,8BACA,CAAA,kBACA,CAAA,iBACA,CAAA,gBACA,CAAA,iBACA,CAAA,iCAIE,mBACE,CAAA,qFAEF,eAEE,CAAA,uEAKF,kBACE,CAAA,YACA,CAAA,iBACA,CAAA,eACA,CAAA,mEAEF,iBACE,CAAA,kBACA,CAAA,cACA,CAAA,yEAEA,eACE,CAAA,iBACA,CAAA,+EAEF,iBACE,CAAA,SACA,CAAA,aACA,CAAA,kBACA,CAAA,OACA,CAAA,UACA,CAAA,gBACA,CAAA,+FAEA,QACE,CAAA,SACA,CAAA,UACA,CAAA,iBACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,kBACA,CAAA,6FAEJ,iBACE,CAAA,yBACA,CAAA,UACA,CAAA,+EAEF,yBACE,CAAA,+FAEA,iBACE,CAAA,OACA,CAAA,UACA,CAAA,UACA,CAAA,cACA,CAAA,iBACA,CAAA,4BACA,CAAA,+BACA,CAAA,6BACA,CAAA,mHAEF,iBACE,CAAA,UACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,iBACA,CAAA,uHAEA,cACE,CAAA,gBACA,CAAA,sBAEV,gBACE,CAAA,iCAYA,WACE,CAAA,gBACA,CAAA,uDAEF,SACI,CAAA,uEAIF,UACE,CAAA,8IAEF,YAEE,CAAA,4CAIF,sBACE,CAAA,WACA,CAAA,6BACA,CAAA,+CAEF,UACE,CAAA,sBACA,CAAA,WACA,CAAA,eACA,CAAA,gBACA,CAAA,8CAEF,eACE,CAAA,eACA,CAAA,UACA,CAAA,gBACA,CAAA,wGAEA,UACE,CAAA,+BAEN,gBACE,CAAA,uDAEF,4BACE,CAAA,8BAIF,gBACE,CAAA,0CAYF,WACE,CAAA,kBAKN,+BACE,CAAA,eACA,CAAA,gBACA,CAAA,mBACA,CAAA,eACA,CAAA,iCAEA,eACE,CAAA,mCAEA,UACE,CAAA,UACA,CAAA,eACA,CAAA,aACA,CAAA,yCAEA,wBACE,CAAA,2CAEN,aACE,CAAA,+CAEA,eACE,CAAA,cACA,CAAA,gBACA,CAAA,qBACA,CAAA,sBAEN,qBA3RU,CAAA,2BA8RR,UA7RU,CAAA,uCAgSV,WACE,CAAA,uCAEF,mCAlSY,CAAA,qDAqSV,qBAvSM,CAAA,UACE,CAAA,4BA0SV,qBA3SQ,CAAA,UACE,CAAA,mCACE,CAAA,6BA8SZ,UA/SU","file":"main.css"} \ No newline at end of file diff --git a/css/main.sass b/css/main.sass index 8581bd1..8829be6 100644 --- a/css/main.sass +++ b/css/main.sass @@ -1,5 +1,12 @@ +$bg_light: #fff +$text_light: #111 +$bg_dark: #111 +$text_dark: #fff +$border_dark: rgba(255,255,255,.125) + body - background: #ffffff + background-color: $bg_light + color: $text_light margin: 0 margin-top: 80px height: 100% @@ -80,7 +87,7 @@ a &:checked + .slider:before transform: translateX(26px) -header.navbar +header background-color: gray border-radius: 0px 0px 30px 30px @@ -274,4 +281,28 @@ footer#footerwrap max-height: 20px max-width: 25px margin-right: 5px - vertical-align: middle \ No newline at end of file + vertical-align: middle + +body[data-theme="dark"] + background-color: $bg_dark + + main + color: $text_dark + + .fa-moon::before + content: "\f185" + + .list-group-item + border-color: $border_dark + + &.sub-component + background-color: $bg_dark + color: $text_dark + + .card + background-color: $bg_dark + color: $text_dark + border-color: $border_dark + + .table + color: $text_dark \ No newline at end of file diff --git a/js/main.js b/js/main.js index 68f4a70..253b3f9 100644 --- a/js/main.js +++ b/js/main.js @@ -27,3 +27,29 @@ function timeago() { }); }); })(); + +var darkSwitch = document.getElementById("darkSwitch"); +window.addEventListener("load", function () { + if (darkSwitch) { + initTheme(); + darkSwitch.addEventListener("change", function () { + resetTheme(); + }); + } +}); + +function initTheme() { + var darkThemeSelected = localStorage.getItem("darkSwitch") !== null && localStorage.getItem("darkSwitch") === "dark"; + darkSwitch.checked = darkThemeSelected; + darkThemeSelected ? document.body.setAttribute("data-theme", "dark") : document.body.removeAttribute("data-theme"); +} + +function resetTheme() { + if (darkSwitch.checked) { + document.body.setAttribute("data-theme", "dark"); + localStorage.setItem("darkSwitch", "dark"); + } else { + document.body.removeAttribute("data-theme"); + localStorage.removeItem("darkSwitch"); + } +} diff --git a/template.php b/template.php index 5f58994..6b6fc64 100644 --- a/template.php +++ b/template.php @@ -101,8 +101,8 @@ class Template -
                      Date: Sat, 20 Mar 2021 19:22:28 +0100 Subject: [PATCH 38/47] remove font-family --- css/main.css | 2 +- css/main.css.map | 2 +- css/main.sass | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/css/main.css b/css/main.css index 0b7ca65..66a7331 100644 --- a/css/main.css +++ b/css/main.css @@ -1 +1 @@ -body{background-color:#fff;color:#111;margin:0;margin-top:80px;height:100%;line-height:24px;font-family:"Open Sans",sans-serif}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status .timeline .card .card-footer p,main.container#dashboard .timeline .card .card-footer p{margin:0}main.container#status .timeline .card .card-footer .card-title,main.container#dashboard .timeline .card .card-footer .card-title{font-size:.9em}main.container#status .timeline .card .card-footer .card-badge,main.container#dashboard .timeline .card .card-footer .card-badge{font-size:.75em}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}body[data-theme=dark]{background-color:#111}body[data-theme=dark] main{color:#fff}body[data-theme=dark] .fa-moon::before{content:""}body[data-theme=dark] .list-group-item{border-color:rgba(255,255,255,.125)}body[data-theme=dark] .list-group-item.sub-component{background-color:#111;color:#fff}body[data-theme=dark] .card{background-color:#111;color:#fff;border-color:rgba(255,255,255,.125)}body[data-theme=dark] .table{color:#fff}/*# sourceMappingURL=main.css.map */ \ No newline at end of file +body{background-color:#fff;color:#111;margin:0;margin-top:80px;height:100%;line-height:24px}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status .timeline .card .card-footer p,main.container#dashboard .timeline .card .card-footer p{margin:0}main.container#status .timeline .card .card-footer .card-title,main.container#dashboard .timeline .card .card-footer .card-title{font-size:.9em}main.container#status .timeline .card .card-footer .card-badge,main.container#dashboard .timeline .card .card-footer .card-badge{font-size:.75em}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}body[data-theme=dark]{background-color:#111}body[data-theme=dark] main{color:#fff}body[data-theme=dark] .fa-moon::before{content:""}body[data-theme=dark] .list-group-item{border-color:rgba(255,255,255,.125)}body[data-theme=dark] .list-group-item.sub-component{background-color:#111;color:#fff}body[data-theme=dark] .card{background-color:#111;color:#fff;border-color:rgba(255,255,255,.125)}body[data-theme=dark] .table{color:#fff}/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/css/main.css.map b/css/main.css.map index 85a7314..5625580 100644 --- a/css/main.css.map +++ b/css/main.css.map @@ -1 +1 @@ -{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KAMA,qBANW,CAAA,UACE,CAAA,QAQX,CAAA,eACA,CAAA,WACA,CAAA,gBACA,CAAA,kCACA,CAAA,mDAEA,eACE,CAAA,IAEJ,WACE,CAAA,cACA,CAAA,EAEF,SACE,CAAA,QACA,CAAA,oBACA,CAAA,gBAEA,oBACE,CAAA,aACA,CAAA,UAEJ,iBACE,CAAA,QAEF,WACE,CAAA,gBACA,CAAA,cACA,CAAA,iBACA,CAAA,gBAEA,iBACE,CAAA,oBACA,CAAA,UACA,CAAA,WACA,CAAA,sBAEA,SACE,CAAA,OACA,CAAA,QACA,CAAA,wBAEF,iBACE,CAAA,cACA,CAAA,KACA,CAAA,MACA,CAAA,OACA,CAAA,QACA,CAAA,qBACA,CACA,cACA,CAAA,+BAEA,iBACE,CAAA,UACA,CAAA,WACA,CAAA,UACA,CAAA,QACA,CAAA,UACA,CAAA,qBACA,CACA,cACA,CAAA,8BAEF,kBACE,CAAA,qCAEA,iBACE,CAAA,8BAGN,wBACE,CAAA,4BAEF,0BACE,CAAA,qCAEF,0BACE,CAAA,OAEN,qBACI,CAAA,+BACA,CAAA,eAEJ,gBACE,CAAA,8BACA,CAAA,kBACA,CAAA,iBACA,CAAA,gBACA,CAAA,iBACA,CAAA,iCAIE,mBACE,CAAA,qFAEF,eAEE,CAAA,uEAKF,kBACE,CAAA,YACA,CAAA,iBACA,CAAA,eACA,CAAA,mEAEF,iBACE,CAAA,kBACA,CAAA,cACA,CAAA,yEAEA,eACE,CAAA,iBACA,CAAA,+EAEF,iBACE,CAAA,SACA,CAAA,aACA,CAAA,kBACA,CAAA,OACA,CAAA,UACA,CAAA,gBACA,CAAA,+FAEA,QACE,CAAA,SACA,CAAA,UACA,CAAA,iBACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,kBACA,CAAA,6FAEJ,iBACE,CAAA,yBACA,CAAA,UACA,CAAA,+EAEF,yBACE,CAAA,+FAEA,iBACE,CAAA,OACA,CAAA,UACA,CAAA,UACA,CAAA,cACA,CAAA,iBACA,CAAA,4BACA,CAAA,+BACA,CAAA,6BACA,CAAA,mHAEF,iBACE,CAAA,UACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,iBACA,CAAA,uHAEA,cACE,CAAA,gBACA,CAAA,6GAIF,QACE,CAAA,iIAEF,cACE,CAAA,iIAEF,eACE,CAAA,sBAEV,gBACE,CAAA,iCAYA,WACE,CAAA,gBACA,CAAA,uDAEF,SACI,CAAA,uEAIF,UACE,CAAA,8IAEF,YAEE,CAAA,4CAIF,sBACE,CAAA,WACA,CAAA,6BACA,CAAA,+CAEF,UACE,CAAA,sBACA,CAAA,WACA,CAAA,eACA,CAAA,gBACA,CAAA,8CAEF,eACE,CAAA,eACA,CAAA,UACA,CAAA,gBACA,CAAA,wGAEA,UACE,CAAA,+BAEN,gBACE,CAAA,uDAEF,4BACE,CAAA,8BAIF,gBACE,CAAA,0CAYF,WACE,CAAA,kBAKN,+BACE,CAAA,eACA,CAAA,gBACA,CAAA,mBACA,CAAA,eACA,CAAA,iCAEA,eACE,CAAA,mCAEA,UACE,CAAA,UACA,CAAA,eACA,CAAA,aACA,CAAA,yCAEA,wBACE,CAAA,2CAEN,aACE,CAAA,+CAEA,eACE,CAAA,cACA,CAAA,gBACA,CAAA,qBACA,CAAA,sBAEN,qBAtSU,CAAA,2BAySR,UAxSU,CAAA,uCA2SV,WACE,CAAA,uCAEF,mCA7SY,CAAA,qDAgTV,qBAlTM,CAAA,UACE,CAAA,4BAqTV,qBAtTQ,CAAA,UACE,CAAA,mCACE,CAAA,6BAyTZ,UA1TU","file":"main.css"} \ No newline at end of file +{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KAMA,qBANW,CAAA,UACE,CAAA,QAQX,CAAA,eACA,CAAA,WACA,CAAA,gBACA,CAAA,mDAEA,eACE,CAAA,IAEJ,WACE,CAAA,cACA,CAAA,EAEF,SACE,CAAA,QACA,CAAA,oBACA,CAAA,gBAEA,oBACE,CAAA,aACA,CAAA,UAEJ,iBACE,CAAA,QAEF,WACE,CAAA,gBACA,CAAA,cACA,CAAA,iBACA,CAAA,gBAEA,iBACE,CAAA,oBACA,CAAA,UACA,CAAA,WACA,CAAA,sBAEA,SACE,CAAA,OACA,CAAA,QACA,CAAA,wBAEF,iBACE,CAAA,cACA,CAAA,KACA,CAAA,MACA,CAAA,OACA,CAAA,QACA,CAAA,qBACA,CACA,cACA,CAAA,+BAEA,iBACE,CAAA,UACA,CAAA,WACA,CAAA,UACA,CAAA,QACA,CAAA,UACA,CAAA,qBACA,CACA,cACA,CAAA,8BAEF,kBACE,CAAA,qCAEA,iBACE,CAAA,8BAGN,wBACE,CAAA,4BAEF,0BACE,CAAA,qCAEF,0BACE,CAAA,OAEN,qBACI,CAAA,+BACA,CAAA,eAEJ,gBACE,CAAA,8BACA,CAAA,kBACA,CAAA,iBACA,CAAA,gBACA,CAAA,iBACA,CAAA,iCAIE,mBACE,CAAA,qFAEF,eAEE,CAAA,uEAKF,kBACE,CAAA,YACA,CAAA,iBACA,CAAA,eACA,CAAA,mEAEF,iBACE,CAAA,kBACA,CAAA,cACA,CAAA,yEAEA,eACE,CAAA,iBACA,CAAA,+EAEF,iBACE,CAAA,SACA,CAAA,aACA,CAAA,kBACA,CAAA,OACA,CAAA,UACA,CAAA,gBACA,CAAA,+FAEA,QACE,CAAA,SACA,CAAA,UACA,CAAA,iBACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,kBACA,CAAA,6FAEJ,iBACE,CAAA,yBACA,CAAA,UACA,CAAA,+EAEF,yBACE,CAAA,+FAEA,iBACE,CAAA,OACA,CAAA,UACA,CAAA,UACA,CAAA,cACA,CAAA,iBACA,CAAA,4BACA,CAAA,+BACA,CAAA,6BACA,CAAA,mHAEF,iBACE,CAAA,UACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,iBACA,CAAA,uHAEA,cACE,CAAA,gBACA,CAAA,6GAIF,QACE,CAAA,iIAEF,cACE,CAAA,iIAEF,eACE,CAAA,sBAEV,gBACE,CAAA,iCAYA,WACE,CAAA,gBACA,CAAA,uDAEF,SACI,CAAA,uEAIF,UACE,CAAA,8IAEF,YAEE,CAAA,4CAIF,sBACE,CAAA,WACA,CAAA,6BACA,CAAA,+CAEF,UACE,CAAA,sBACA,CAAA,WACA,CAAA,eACA,CAAA,gBACA,CAAA,8CAEF,eACE,CAAA,eACA,CAAA,UACA,CAAA,gBACA,CAAA,wGAEA,UACE,CAAA,+BAEN,gBACE,CAAA,uDAEF,4BACE,CAAA,8BAIF,gBACE,CAAA,0CAYF,WACE,CAAA,kBAKN,+BACE,CAAA,eACA,CAAA,gBACA,CAAA,mBACA,CAAA,eACA,CAAA,iCAEA,eACE,CAAA,mCAEA,UACE,CAAA,UACA,CAAA,eACA,CAAA,aACA,CAAA,yCAEA,wBACE,CAAA,2CAEN,aACE,CAAA,+CAEA,eACE,CAAA,cACA,CAAA,gBACA,CAAA,qBACA,CAAA,sBAEN,qBArSU,CAAA,2BAwSR,UAvSU,CAAA,uCA0SV,WACE,CAAA,uCAEF,mCA5SY,CAAA,qDA+SV,qBAjTM,CAAA,UACE,CAAA,4BAoTV,qBArTQ,CAAA,UACE,CAAA,mCACE,CAAA,6BAwTZ,UAzTU","file":"main.css"} \ No newline at end of file diff --git a/css/main.sass b/css/main.sass index 5b9c6ac..7be71c0 100644 --- a/css/main.sass +++ b/css/main.sass @@ -11,7 +11,6 @@ body margin-top: 80px height: 100% line-height: 24px - font-family: "Open Sans", sans-serif .h1, .h2, .h3, h1, h2, h3 margin-top: 18px From b7b370b1c7df8310dd0aeed871c9123e9a16fea9 Mon Sep 17 00:00:00 2001 From: Tealk Date: Sun, 21 Mar 2021 12:56:32 +0100 Subject: [PATCH 39/47] missin quotes --- admin/service.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/service.php b/admin/service.php index 9c68e96..9a1cfba 100644 --- a/admin/service.php +++ b/admin/service.php @@ -85,5 +85,5 @@ if (!$boolEdit) { echo ''; } ?> - + \ No newline at end of file From 335f8428475c9934754719b04a36085b55128e42 Mon Sep 17 00:00:00 2001 From: Tealk Date: Sun, 21 Mar 2021 12:58:05 +0100 Subject: [PATCH 40/47] unnecessary code removed --- classes/constellation.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/classes/constellation.php b/classes/constellation.php index 245bf21..a0de17e 100644 --- a/classes/constellation.php +++ b/classes/constellation.php @@ -92,13 +92,6 @@ class Constellation $array[] = new Service(0, _("No services"), -1); } if (!$admin) { -?> - -'; //$arrCompletedGroups = array(); foreach ($array as $service) { From bf5e0a6476a3147fd5206c61a7693fef0fc64639 Mon Sep 17 00:00:00 2001 From: Tealk Date: Sun, 21 Mar 2021 12:58:26 +0100 Subject: [PATCH 41/47] mobile menu fixed --- template.php | 104 ++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/template.php b/template.php index 6b6fc64..8f642d2 100644 --- a/template.php +++ b/template.php @@ -102,56 +102,60 @@ class Template
                      - +
                      + +
                      Date: Sun, 21 Mar 2021 13:25:57 +0100 Subject: [PATCH 42/47] dashboard status text alignment right --- css/main.css | 2 +- css/main.css.map | 2 +- css/main.sass | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/css/main.css b/css/main.css index 66a7331..7d9fe33 100644 --- a/css/main.css +++ b/css/main.css @@ -1 +1 @@ -body{background-color:#fff;color:#111;margin:0;margin-top:80px;height:100%;line-height:24px}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status .timeline .card .card-footer p,main.container#dashboard .timeline .card .card-footer p{margin:0}main.container#status .timeline .card .card-footer .card-title,main.container#dashboard .timeline .card .card-footer .card-title{font-size:.9em}main.container#status .timeline .card .card-footer .card-badge,main.container#dashboard .timeline .card .card-footer .card-badge{font-size:.75em}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}body[data-theme=dark]{background-color:#111}body[data-theme=dark] main{color:#fff}body[data-theme=dark] .fa-moon::before{content:""}body[data-theme=dark] .list-group-item{border-color:rgba(255,255,255,.125)}body[data-theme=dark] .list-group-item.sub-component{background-color:#111;color:#fff}body[data-theme=dark] .card{background-color:#111;color:#fff;border-color:rgba(255,255,255,.125)}body[data-theme=dark] .table{color:#fff}/*# sourceMappingURL=main.css.map */ \ No newline at end of file +body{background-color:#fff;color:#111;margin:0;margin-top:80px;height:100%;line-height:24px}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status .timeline .card .card-footer p,main.container#dashboard .timeline .card .card-footer p{margin:0}main.container#status .timeline .card .card-footer .card-title,main.container#dashboard .timeline .card .card-footer .card-title{font-size:.9em}main.container#status .timeline .card .card-footer .card-badge,main.container#dashboard .timeline .card .card-footer .card-badge{font-size:.75em}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;display:block;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}body[data-theme=dark]{background-color:#111}body[data-theme=dark] main{color:#fff}body[data-theme=dark] .fa-moon::before{content:""}body[data-theme=dark] .list-group-item{border-color:rgba(255,255,255,.125)}body[data-theme=dark] .list-group-item.sub-component{background-color:#111;color:#fff}body[data-theme=dark] .card{background-color:#111;color:#fff;border-color:rgba(255,255,255,.125)}body[data-theme=dark] .table{color:#fff}/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/css/main.css.map b/css/main.css.map index 5625580..c883b6e 100644 --- a/css/main.css.map +++ b/css/main.css.map @@ -1 +1 @@ -{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KAMA,qBANW,CAAA,UACE,CAAA,QAQX,CAAA,eACA,CAAA,WACA,CAAA,gBACA,CAAA,mDAEA,eACE,CAAA,IAEJ,WACE,CAAA,cACA,CAAA,EAEF,SACE,CAAA,QACA,CAAA,oBACA,CAAA,gBAEA,oBACE,CAAA,aACA,CAAA,UAEJ,iBACE,CAAA,QAEF,WACE,CAAA,gBACA,CAAA,cACA,CAAA,iBACA,CAAA,gBAEA,iBACE,CAAA,oBACA,CAAA,UACA,CAAA,WACA,CAAA,sBAEA,SACE,CAAA,OACA,CAAA,QACA,CAAA,wBAEF,iBACE,CAAA,cACA,CAAA,KACA,CAAA,MACA,CAAA,OACA,CAAA,QACA,CAAA,qBACA,CACA,cACA,CAAA,+BAEA,iBACE,CAAA,UACA,CAAA,WACA,CAAA,UACA,CAAA,QACA,CAAA,UACA,CAAA,qBACA,CACA,cACA,CAAA,8BAEF,kBACE,CAAA,qCAEA,iBACE,CAAA,8BAGN,wBACE,CAAA,4BAEF,0BACE,CAAA,qCAEF,0BACE,CAAA,OAEN,qBACI,CAAA,+BACA,CAAA,eAEJ,gBACE,CAAA,8BACA,CAAA,kBACA,CAAA,iBACA,CAAA,gBACA,CAAA,iBACA,CAAA,iCAIE,mBACE,CAAA,qFAEF,eAEE,CAAA,uEAKF,kBACE,CAAA,YACA,CAAA,iBACA,CAAA,eACA,CAAA,mEAEF,iBACE,CAAA,kBACA,CAAA,cACA,CAAA,yEAEA,eACE,CAAA,iBACA,CAAA,+EAEF,iBACE,CAAA,SACA,CAAA,aACA,CAAA,kBACA,CAAA,OACA,CAAA,UACA,CAAA,gBACA,CAAA,+FAEA,QACE,CAAA,SACA,CAAA,UACA,CAAA,iBACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,kBACA,CAAA,6FAEJ,iBACE,CAAA,yBACA,CAAA,UACA,CAAA,+EAEF,yBACE,CAAA,+FAEA,iBACE,CAAA,OACA,CAAA,UACA,CAAA,UACA,CAAA,cACA,CAAA,iBACA,CAAA,4BACA,CAAA,+BACA,CAAA,6BACA,CAAA,mHAEF,iBACE,CAAA,UACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,iBACA,CAAA,uHAEA,cACE,CAAA,gBACA,CAAA,6GAIF,QACE,CAAA,iIAEF,cACE,CAAA,iIAEF,eACE,CAAA,sBAEV,gBACE,CAAA,iCAYA,WACE,CAAA,gBACA,CAAA,uDAEF,SACI,CAAA,uEAIF,UACE,CAAA,8IAEF,YAEE,CAAA,4CAIF,sBACE,CAAA,WACA,CAAA,6BACA,CAAA,+CAEF,UACE,CAAA,sBACA,CAAA,WACA,CAAA,eACA,CAAA,gBACA,CAAA,8CAEF,eACE,CAAA,eACA,CAAA,UACA,CAAA,gBACA,CAAA,wGAEA,UACE,CAAA,+BAEN,gBACE,CAAA,uDAEF,4BACE,CAAA,8BAIF,gBACE,CAAA,0CAYF,WACE,CAAA,kBAKN,+BACE,CAAA,eACA,CAAA,gBACA,CAAA,mBACA,CAAA,eACA,CAAA,iCAEA,eACE,CAAA,mCAEA,UACE,CAAA,UACA,CAAA,eACA,CAAA,aACA,CAAA,yCAEA,wBACE,CAAA,2CAEN,aACE,CAAA,+CAEA,eACE,CAAA,cACA,CAAA,gBACA,CAAA,qBACA,CAAA,sBAEN,qBArSU,CAAA,2BAwSR,UAvSU,CAAA,uCA0SV,WACE,CAAA,uCAEF,mCA5SY,CAAA,qDA+SV,qBAjTM,CAAA,UACE,CAAA,4BAoTV,qBArTQ,CAAA,UACE,CAAA,mCACE,CAAA,6BAwTZ,UAzTU","file":"main.css"} \ No newline at end of file +{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KAMA,qBANW,CAAA,UACE,CAAA,QAQX,CAAA,eACA,CAAA,WACA,CAAA,gBACA,CAAA,mDAEA,eACE,CAAA,IAEJ,WACE,CAAA,cACA,CAAA,EAEF,SACE,CAAA,QACA,CAAA,oBACA,CAAA,gBAEA,oBACE,CAAA,aACA,CAAA,UAEJ,iBACE,CAAA,QAEF,WACE,CAAA,gBACA,CAAA,cACA,CAAA,iBACA,CAAA,gBAEA,iBACE,CAAA,oBACA,CAAA,UACA,CAAA,WACA,CAAA,sBAEA,SACE,CAAA,OACA,CAAA,QACA,CAAA,wBAEF,iBACE,CAAA,cACA,CAAA,KACA,CAAA,MACA,CAAA,OACA,CAAA,QACA,CAAA,qBACA,CACA,cACA,CAAA,+BAEA,iBACE,CAAA,UACA,CAAA,WACA,CAAA,UACA,CAAA,QACA,CAAA,UACA,CAAA,qBACA,CACA,cACA,CAAA,8BAEF,kBACE,CAAA,qCAEA,iBACE,CAAA,8BAGN,wBACE,CAAA,4BAEF,0BACE,CAAA,qCAEF,0BACE,CAAA,OAEN,qBACI,CAAA,+BACA,CAAA,eAEJ,gBACE,CAAA,8BACA,CAAA,kBACA,CAAA,iBACA,CAAA,gBACA,CAAA,iBACA,CAAA,iCAIE,mBACE,CAAA,qFAEF,eAEE,CAAA,uEAKF,kBACE,CAAA,YACA,CAAA,iBACA,CAAA,eACA,CAAA,mEAEF,iBACE,CAAA,kBACA,CAAA,cACA,CAAA,yEAEA,eACE,CAAA,iBACA,CAAA,+EAEF,iBACE,CAAA,SACA,CAAA,aACA,CAAA,kBACA,CAAA,OACA,CAAA,UACA,CAAA,gBACA,CAAA,+FAEA,QACE,CAAA,SACA,CAAA,UACA,CAAA,iBACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,kBACA,CAAA,6FAEJ,iBACE,CAAA,yBACA,CAAA,UACA,CAAA,+EAEF,yBACE,CAAA,+FAEA,iBACE,CAAA,OACA,CAAA,UACA,CAAA,UACA,CAAA,cACA,CAAA,iBACA,CAAA,4BACA,CAAA,+BACA,CAAA,6BACA,CAAA,mHAEF,iBACE,CAAA,UACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,iBACA,CAAA,uHAEA,cACE,CAAA,gBACA,CAAA,6GAIF,QACE,CAAA,iIAEF,cACE,CAAA,iIAEF,eACE,CAAA,sBAEV,gBACE,CAAA,iCAYA,WACE,CAAA,aACA,CAAA,gBACA,CAAA,uDAEF,SACI,CAAA,uEAIF,UACE,CAAA,8IAEF,YAEE,CAAA,4CAIF,sBACE,CAAA,WACA,CAAA,6BACA,CAAA,+CAEF,UACE,CAAA,sBACA,CAAA,WACA,CAAA,eACA,CAAA,gBACA,CAAA,8CAEF,eACE,CAAA,eACA,CAAA,UACA,CAAA,gBACA,CAAA,wGAEA,UACE,CAAA,+BAEN,gBACE,CAAA,uDAEF,4BACE,CAAA,8BAIF,gBACE,CAAA,0CAYF,WACE,CAAA,kBAKN,+BACE,CAAA,eACA,CAAA,gBACA,CAAA,mBACA,CAAA,eACA,CAAA,iCAEA,eACE,CAAA,mCAEA,UACE,CAAA,UACA,CAAA,eACA,CAAA,aACA,CAAA,yCAEA,wBACE,CAAA,2CAEN,aACE,CAAA,+CAEA,eACE,CAAA,cACA,CAAA,gBACA,CAAA,qBACA,CAAA,sBAEN,qBAtSU,CAAA,2BAySR,UAxSU,CAAA,uCA2SV,WACE,CAAA,uCAEF,mCA7SY,CAAA,qDAgTV,qBAlTM,CAAA,UACE,CAAA,4BAqTV,qBAtTQ,CAAA,UACE,CAAA,mCACE,CAAA,6BAyTZ,UA1TU","file":"main.css"} \ No newline at end of file diff --git a/css/main.sass b/css/main.sass index 7be71c0..8b87483 100644 --- a/css/main.sass +++ b/css/main.sass @@ -201,6 +201,7 @@ main.container #status width: 230px + display: block text-align: right .card-header.bg-primary input From a76211de8b44f19dd854a1949667f0813164630f Mon Sep 17 00:00:00 2001 From: Tealk Date: Sun, 21 Mar 2021 14:01:51 +0100 Subject: [PATCH 43/47] fix card title width --- css/main.css | 2 +- css/main.css.map | 2 +- css/main.sass | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/css/main.css b/css/main.css index 7d9fe33..d9a181b 100644 --- a/css/main.css +++ b/css/main.css @@ -1 +1 @@ -body{background-color:#fff;color:#111;margin:0;margin-top:80px;height:100%;line-height:24px}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status .timeline .card .card-footer p,main.container#dashboard .timeline .card .card-footer p{margin:0}main.container#status .timeline .card .card-footer .card-title,main.container#dashboard .timeline .card .card-footer .card-title{font-size:.9em}main.container#status .timeline .card .card-footer .card-badge,main.container#dashboard .timeline .card .card-footer .card-badge{font-size:.75em}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;display:block;text-align:right}main.container#dashboard .card-header.bg-primary input{width:80%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}body[data-theme=dark]{background-color:#111}body[data-theme=dark] main{color:#fff}body[data-theme=dark] .fa-moon::before{content:""}body[data-theme=dark] .list-group-item{border-color:rgba(255,255,255,.125)}body[data-theme=dark] .list-group-item.sub-component{background-color:#111;color:#fff}body[data-theme=dark] .card{background-color:#111;color:#fff;border-color:rgba(255,255,255,.125)}body[data-theme=dark] .table{color:#fff}/*# sourceMappingURL=main.css.map */ \ No newline at end of file +body{background-color:#fff;color:#111;margin:0;margin-top:80px;height:100%;line-height:24px}body .h1,body .h2,body .h3,body h1,body h2,body h3{margin-top:18px}img{height:auto;max-width:100%}a{padding:0;margin:0;text-decoration:none}a:hover,a:focus{text-decoration:none;color:#f5f4f4}.centered{text-align:center}#switch{height:auto;line-height:34px;font-size:25px;margin-bottom:5px}#switch .switch{position:relative;display:inline-block;width:60px;height:34px}#switch .switch input{opacity:0;width:0;height:0}#switch .switch .slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:.4s}#switch .switch .slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}#switch .switch .slider.round{border-radius:34px}#switch .switch .slider.round:before{border-radius:50%}#switch input:checked+.slider{background-color:#2196f3}#switch input:focus+.slider{box-shadow:0 0 1px #2196f3}#switch input:checked+.slider:before{transform:translateX(26px)}header{background-color:gray;border-radius:0px 0px 30px 30px}main.container{max-width:1024px;min-height:calc(100vh - 157px);padding-right:15px;padding-left:15px;margin-left:auto;margin-right:auto}main.container#install .settings{padding-bottom:25px}main.container#install .settings,main.container#install form .card:not(:first-child){margin-top:30px}main.container#status #status-big,main.container#dashboard #status-big{margin-bottom:20px;padding:15px;border-radius:5px;font-size:1.3em}main.container#status .timeline,main.container#dashboard .timeline{position:relative;padding:0 0px 10px;margin-top:4px}main.container#status .timeline h3,main.container#dashboard .timeline h3{margin-top:40px;padding-left:70px}main.container#status .timeline .line,main.container#dashboard .timeline .line{position:absolute;width:2px;display:block;background:#c2c2c2;top:0px;bottom:0px;margin-left:31px}main.container#status .timeline .line::before,main.container#dashboard .timeline .line::before{top:-4px;left:-4px;content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#c2c2c2}main.container#status .timeline .servicelist,main.container#dashboard .timeline .servicelist{position:relative;margin:10px 0px 21px 70px;clear:both}main.container#status .timeline .card,main.container#dashboard .timeline .card{margin:10px 0px 21px 70px}main.container#status .timeline .card::before,main.container#dashboard .timeline .card::before{position:absolute;top:8px;left:-24px;content:"";border:inherit;border-width:12px;border-top-color:transparent;border-bottom-color:transparent;border-left-color:transparent}main.container#status .timeline .card .card-colore.icon,main.container#dashboard .timeline .card .card-colore.icon{position:absolute;left:-59px;width:40px;height:40px;border-radius:50%;text-align:center}main.container#status .timeline .card .card-colore.icon i,main.container#dashboard .timeline .card .card-colore.icon i{font-size:20px;line-height:40px}main.container#status .timeline .card .card-footer p,main.container#dashboard .timeline .card .card-footer p{margin:0}main.container#status .timeline .card .card-footer .card-title,main.container#dashboard .timeline .card .card-footer .card-title{font-size:.9em}main.container#status .timeline .card .card-footer .card-badge,main.container#dashboard .timeline .card .card-footer .card-badge{font-size:.75em}main.container#status{font-size:1.05em}main.container#dashboard #status{width:230px;display:block;text-align:right}main.container#dashboard .card-header.bg-primary input#title{width:70%}main.container#dashboard .card-header:not(.border-primary) input#title{width:100%}main.container#dashboard .card-header:not(.border-primary) #time,main.container#dashboard .card-header:not(.border-primary) #end_time_wrapper{display:none}main.container#dashboard article.card input{background:transparent;border:none;border-bottom:1px #fff outset}main.container#dashboard article.card textarea{width:100%;background:transparent;border:none;resize:vertical;min-height:100px}main.container#dashboard article.card .delete{margin-left:5px;font-size:1.2em;color:#fff;line-height:25px}main.container#dashboard article.card .delete:hover,main.container#dashboard article.card .delete:focus{color:#eee}main.container#dashboard #type{margin-left:70px}main.container#dashboard #status-container.error input{box-shadow:0px 0 2px 1px red}main.container#login .wrapper{padding-top:20px}main.container#settings .input-group-text{width:230px}footer#footerwrap{border-radius:30px 30px 0px 0px;min-height:60px;padding-top:15px;padding-bottom:10px;background:gray}footer#footerwrap .dropdown-menu{background:gray}footer#footerwrap .dropdown-menu a{color:#fff;width:100%;padding:2px 5px;display:block}footer#footerwrap .dropdown-menu a:hover{background-color:#2f8ad8}footer#footerwrap .input-group.dropup.mb-3{display:block}footer#footerwrap .input-group.dropup.mb-3 img{max-height:20px;max-width:25px;margin-right:5px;vertical-align:middle}body[data-theme=dark]{background-color:#111}body[data-theme=dark] main{color:#fff}body[data-theme=dark] .fa-moon::before{content:""}body[data-theme=dark] .list-group-item{border-color:rgba(255,255,255,.125)}body[data-theme=dark] .list-group-item.sub-component{background-color:#111;color:#fff}body[data-theme=dark] .card{background-color:#111;color:#fff;border-color:rgba(255,255,255,.125)}body[data-theme=dark] .table{color:#fff}/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/css/main.css.map b/css/main.css.map index c883b6e..14546a1 100644 --- a/css/main.css.map +++ b/css/main.css.map @@ -1 +1 @@ -{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KAMA,qBANW,CAAA,UACE,CAAA,QAQX,CAAA,eACA,CAAA,WACA,CAAA,gBACA,CAAA,mDAEA,eACE,CAAA,IAEJ,WACE,CAAA,cACA,CAAA,EAEF,SACE,CAAA,QACA,CAAA,oBACA,CAAA,gBAEA,oBACE,CAAA,aACA,CAAA,UAEJ,iBACE,CAAA,QAEF,WACE,CAAA,gBACA,CAAA,cACA,CAAA,iBACA,CAAA,gBAEA,iBACE,CAAA,oBACA,CAAA,UACA,CAAA,WACA,CAAA,sBAEA,SACE,CAAA,OACA,CAAA,QACA,CAAA,wBAEF,iBACE,CAAA,cACA,CAAA,KACA,CAAA,MACA,CAAA,OACA,CAAA,QACA,CAAA,qBACA,CACA,cACA,CAAA,+BAEA,iBACE,CAAA,UACA,CAAA,WACA,CAAA,UACA,CAAA,QACA,CAAA,UACA,CAAA,qBACA,CACA,cACA,CAAA,8BAEF,kBACE,CAAA,qCAEA,iBACE,CAAA,8BAGN,wBACE,CAAA,4BAEF,0BACE,CAAA,qCAEF,0BACE,CAAA,OAEN,qBACI,CAAA,+BACA,CAAA,eAEJ,gBACE,CAAA,8BACA,CAAA,kBACA,CAAA,iBACA,CAAA,gBACA,CAAA,iBACA,CAAA,iCAIE,mBACE,CAAA,qFAEF,eAEE,CAAA,uEAKF,kBACE,CAAA,YACA,CAAA,iBACA,CAAA,eACA,CAAA,mEAEF,iBACE,CAAA,kBACA,CAAA,cACA,CAAA,yEAEA,eACE,CAAA,iBACA,CAAA,+EAEF,iBACE,CAAA,SACA,CAAA,aACA,CAAA,kBACA,CAAA,OACA,CAAA,UACA,CAAA,gBACA,CAAA,+FAEA,QACE,CAAA,SACA,CAAA,UACA,CAAA,iBACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,kBACA,CAAA,6FAEJ,iBACE,CAAA,yBACA,CAAA,UACA,CAAA,+EAEF,yBACE,CAAA,+FAEA,iBACE,CAAA,OACA,CAAA,UACA,CAAA,UACA,CAAA,cACA,CAAA,iBACA,CAAA,4BACA,CAAA,+BACA,CAAA,6BACA,CAAA,mHAEF,iBACE,CAAA,UACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,iBACA,CAAA,uHAEA,cACE,CAAA,gBACA,CAAA,6GAIF,QACE,CAAA,iIAEF,cACE,CAAA,iIAEF,eACE,CAAA,sBAEV,gBACE,CAAA,iCAYA,WACE,CAAA,aACA,CAAA,gBACA,CAAA,uDAEF,SACI,CAAA,uEAIF,UACE,CAAA,8IAEF,YAEE,CAAA,4CAIF,sBACE,CAAA,WACA,CAAA,6BACA,CAAA,+CAEF,UACE,CAAA,sBACA,CAAA,WACA,CAAA,eACA,CAAA,gBACA,CAAA,8CAEF,eACE,CAAA,eACA,CAAA,UACA,CAAA,gBACA,CAAA,wGAEA,UACE,CAAA,+BAEN,gBACE,CAAA,uDAEF,4BACE,CAAA,8BAIF,gBACE,CAAA,0CAYF,WACE,CAAA,kBAKN,+BACE,CAAA,eACA,CAAA,gBACA,CAAA,mBACA,CAAA,eACA,CAAA,iCAEA,eACE,CAAA,mCAEA,UACE,CAAA,UACA,CAAA,eACA,CAAA,aACA,CAAA,yCAEA,wBACE,CAAA,2CAEN,aACE,CAAA,+CAEA,eACE,CAAA,cACA,CAAA,gBACA,CAAA,qBACA,CAAA,sBAEN,qBAtSU,CAAA,2BAySR,UAxSU,CAAA,uCA2SV,WACE,CAAA,uCAEF,mCA7SY,CAAA,qDAgTV,qBAlTM,CAAA,UACE,CAAA,4BAqTV,qBAtTQ,CAAA,UACE,CAAA,mCACE,CAAA,6BAyTZ,UA1TU","file":"main.css"} \ No newline at end of file +{"version":3,"sources":["main.sass"],"names":[],"mappings":"AAAA,KAMA,qBANW,CAAA,UACE,CAAA,QAQX,CAAA,eACA,CAAA,WACA,CAAA,gBACA,CAAA,mDAEA,eACE,CAAA,IAEJ,WACE,CAAA,cACA,CAAA,EAEF,SACE,CAAA,QACA,CAAA,oBACA,CAAA,gBAEA,oBACE,CAAA,aACA,CAAA,UAEJ,iBACE,CAAA,QAEF,WACE,CAAA,gBACA,CAAA,cACA,CAAA,iBACA,CAAA,gBAEA,iBACE,CAAA,oBACA,CAAA,UACA,CAAA,WACA,CAAA,sBAEA,SACE,CAAA,OACA,CAAA,QACA,CAAA,wBAEF,iBACE,CAAA,cACA,CAAA,KACA,CAAA,MACA,CAAA,OACA,CAAA,QACA,CAAA,qBACA,CACA,cACA,CAAA,+BAEA,iBACE,CAAA,UACA,CAAA,WACA,CAAA,UACA,CAAA,QACA,CAAA,UACA,CAAA,qBACA,CACA,cACA,CAAA,8BAEF,kBACE,CAAA,qCAEA,iBACE,CAAA,8BAGN,wBACE,CAAA,4BAEF,0BACE,CAAA,qCAEF,0BACE,CAAA,OAEN,qBACI,CAAA,+BACA,CAAA,eAEJ,gBACE,CAAA,8BACA,CAAA,kBACA,CAAA,iBACA,CAAA,gBACA,CAAA,iBACA,CAAA,iCAIE,mBACE,CAAA,qFAEF,eAEE,CAAA,uEAKF,kBACE,CAAA,YACA,CAAA,iBACA,CAAA,eACA,CAAA,mEAEF,iBACE,CAAA,kBACA,CAAA,cACA,CAAA,yEAEA,eACE,CAAA,iBACA,CAAA,+EAEF,iBACE,CAAA,SACA,CAAA,aACA,CAAA,kBACA,CAAA,OACA,CAAA,UACA,CAAA,gBACA,CAAA,+FAEA,QACE,CAAA,SACA,CAAA,UACA,CAAA,iBACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,kBACA,CAAA,6FAEJ,iBACE,CAAA,yBACA,CAAA,UACA,CAAA,+EAEF,yBACE,CAAA,+FAEA,iBACE,CAAA,OACA,CAAA,UACA,CAAA,UACA,CAAA,cACA,CAAA,iBACA,CAAA,4BACA,CAAA,+BACA,CAAA,6BACA,CAAA,mHAEF,iBACE,CAAA,UACA,CAAA,UACA,CAAA,WACA,CAAA,iBACA,CAAA,iBACA,CAAA,uHAEA,cACE,CAAA,gBACA,CAAA,6GAIF,QACE,CAAA,iIAEF,cACE,CAAA,iIAEF,eACE,CAAA,sBAEV,gBACE,CAAA,iCAYA,WACE,CAAA,aACA,CAAA,gBACA,CAAA,6DAEF,SACI,CAAA,uEAIF,UACE,CAAA,8IAEF,YAEE,CAAA,4CAIF,sBACE,CAAA,WACA,CAAA,6BACA,CAAA,+CAEF,UACE,CAAA,sBACA,CAAA,WACA,CAAA,eACA,CAAA,gBACA,CAAA,8CAEF,eACE,CAAA,eACA,CAAA,UACA,CAAA,gBACA,CAAA,wGAEA,UACE,CAAA,+BAEN,gBACE,CAAA,uDAEF,4BACE,CAAA,8BAIF,gBACE,CAAA,0CAYF,WACE,CAAA,kBAKN,+BACE,CAAA,eACA,CAAA,gBACA,CAAA,mBACA,CAAA,eACA,CAAA,iCAEA,eACE,CAAA,mCAEA,UACE,CAAA,UACA,CAAA,eACA,CAAA,aACA,CAAA,yCAEA,wBACE,CAAA,2CAEN,aACE,CAAA,+CAEA,eACE,CAAA,cACA,CAAA,gBACA,CAAA,qBACA,CAAA,sBAEN,qBAtSU,CAAA,2BAySR,UAxSU,CAAA,uCA2SV,WACE,CAAA,uCAEF,mCA7SY,CAAA,qDAgTV,qBAlTM,CAAA,UACE,CAAA,4BAqTV,qBAtTQ,CAAA,UACE,CAAA,mCACE,CAAA,6BAyTZ,UA1TU","file":"main.css"} \ No newline at end of file diff --git a/css/main.sass b/css/main.sass index 8b87483..834176d 100644 --- a/css/main.sass +++ b/css/main.sass @@ -204,8 +204,8 @@ main.container display: block text-align: right - .card-header.bg-primary input - width: 80% + .card-header.bg-primary input#title + width: 70% .card-header:not(.border-primary) From ad8e5ed94499f2bb89ebcc524ccc0743aaeb7a90 Mon Sep 17 00:00:00 2001 From: Tealk Date: Tue, 13 Apr 2021 19:11:17 +0200 Subject: [PATCH 44/47] add admin link --- template.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/template.php b/template.php index 8f642d2..6783474 100644 --- a/template.php +++ b/template.php @@ -105,7 +105,7 @@ class Template
                  -
                  +

                  From eb2f8b78dd602c6e5719aefa54aeaad5fe25ae9a Mon Sep 17 00:00:00 2001 From: Tealk Date: Thu, 15 Apr 2021 16:17:46 +0200 Subject: [PATCH 47/47] open translation in new tab and add security --- template.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/template.php b/template.php index d4cb799..c3c8bba 100644 --- a/template.php +++ b/template.php @@ -199,9 +199,9 @@ class Template