1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-09-16 17:30:11 +00:00

organise code, use typescript, add more modals

This commit is contained in:
Harvey Tindall 2020-12-20 22:49:54 +00:00
parent cb280975b7
commit e50a7948e7
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
11 changed files with 705 additions and 473 deletions

279
2
View File

@ -1,279 +0,0 @@
.pageContainer {
margin: 5% 20% 5% 20%;
}
@media (max-width: 1100px) {
.pageContainer {
margin: 2%;
}
}
/*input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
}*/
.contactBox {
color: grey;
}
#container {
margin-top: 5%;
margin-bottom: 5%;
}
.tabText {
font-size: 2rem;
}
.mb-1 {
margin-bottom: 1rem;
}
.mb-half {
margin-bottom: 0.5rem;
}
.pb-1 {
padding-bottom: 1rem;
}
.pl-1 {
padding-left: 1rem;
}
.mr-1 {
margin-right: 1rem;
}
.ml-1 {
margin-left: 1rem;
}
.mb-2 {
margin-bottom: 2rem;
}
.mt-half {
margin-top: 0.5rem;
}
.inv-codearea {
/*width: 40%;*/
}
.al {
text-align: left;
}
.inline-block {
display: inline-block;
}
.ar {
text-align: right;
}
.monospace {
background-color: inherit;
}
.mt-half {
margin-top: 0.5rem;
}
.table-header {
padding-left: 0.5rem;
padding-bottom: 0.2rem;
}
.inv {
overflow: hidden;
}
.inv-header {
display: flex;
justify-content: space-between;
}
.button-input {
display: flex;
justify-content: space-between;
}
/*.inv-details {
display: flex;
justify-content: space-between;
}*/
/*.invites {
transition: max-height 1s cubic-bezier(0.550, 0.055, 0.675, 0.190);
}*/
.inv-details {
}
.inv-row {
display: flex;
justify-content: space-between;
align-items: top;
}
/*.inv-profilearea {
align-items: top;
}*/
.ib {
display: inline-block;
}
.inv-profileselect {
min-width: 100%;
}
.inv-table {
font-size: 0.8rem;
}
.no-lp {
padding-left: 0px;
}
.block { display: block; }
.hiding {
animation: slide-out 0.1s cubic-bezier(0.550, 0.055, 0.675, 0.190) forwards;
}
.hidden {
display: none;
}
.visible {
display: block;
/*animation: fade-in 0.2s cubic-bezier(0.550, 0.055, 0.675, 0.190) forwards;*/
}
@keyframes fade-in {
from {
opacity: 0;
visibility: hidden;
}
to {
opacity: 1;
visibility: visible;
}
}
@keyframes slide-out {
from {
opacity: 1;
visibility: visible;
}
to {
opacity: 0;
visibility: hidden;
}
}
.toggle-details {
display: none;
}
.rotated {
transform: rotate(180deg);
-webkit-transition: all 0.3s cubic-bezier(0,.89,.27,.92);
-moz-transition: all 0.3s cubic-bezier(0,.89,.27,.92);
-o-transition: all 0.3s cubic-bezier(0,.89,.27,.92);
transition: all 0.3s cubic-bezier(0,.89,.27,.92); /* easeInOutQuart */
}
.not-rotated {
transform: rotate(0deg);
-webkit-transition: all 0.3s cubic-bezier(0,.89,.27,.92);
-moz-transition: all 0.3s cubic-bezier(0,.89,.27,.92);
-o-transition: all 0.3s cubic-bezier(0,.89,.27,.92);
transition: all 0.3s cubic-bezier(0,.89,.27,.92); /* easeInOutQuart */
}
.row {
display: flex;
flex-wrap: wrap;
}
.col {
flex: 1;
margin: 0.5rem;
}
@media screen and (max-width: 400px) {
.row {
flex-direction: column;
}
.col {
flex: 45%;
}
}
.input {
box-sizing: border-box;
}
.button-lg {
height: 3rem;
}
.full-width {
box-sizing: border-box;
width: 100%;
justify-content: center;
}
.unfocused {
display: none;
}
.fr {
float: right;
}
.stealth-input-hidden {
border-style: none;
--fallback-box-shadow: none;
--field-hover-box-shadow: none;
--field-focus-box-shadow: none;
padding-top: 0.1rem;
padding-bottom: 0.1rem;
}
.stealth-input {
font-size: 1rem;
padding-top: 0.1rem;
padding-bottom: 0.1rem;
margin-left: 0.5rem;
margin-right: 1rem;
max-width: 50%;
}
.settings-section-button {
box-sizing: border-box;
width: 100%;
height: 2.5rem;
--button-filter-brightness: 90%;
}
.settings-section-button.selected {
--button-filter-brightness: 85%;
filter: brightness(85%);
}
.text-critical {
color: var(--color-critical-normal-content);
}
.aside.small {
font-size: 0.8rem;
padding: 0.8rem;
}
.setting {
margin-bottom: 0.25rem;
}
.support.large {
font-size: 1rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,40%);
}
.shown {
display: block;
}
@keyframes modal-show {
from {
top: -5rem;
opacity: 0;
}
to {
top: 0;
opacity: 1;
}
}
.modal-content {
position: relative;
margin: 10% auto;
width: 60%;
}
.shown .modal-content {
animation: modal-show 0.5s cubic-bezier(.41,.47,0,.91);
}
@media screen and (max-width: 400px) {
.modal-content {
width: 90%;
}
}

View File

@ -1,3 +1,5 @@
@import "modal.css";
.pageContainer {
margin: 5% 20% 5% 20%;
}
@ -240,54 +242,3 @@ input[type=number] {
font-size: 1rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,40%);
}
.modal-shown {
display: block;
}
@keyframes modal-hide {
from { opacity: 1; }
to { opacity: 0; }
}
.modal-hiding {
animation: modal-hide 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@keyframes modal-content-show {
from {
opacity: 0;
top: -6rem;
}
to {
opacity: 1;
top: 0;
}
}
.modal-content {
position: relative;
margin: 10% auto;
width: 30%;
}
.modal-shown .modal-content {
animation: modal-content-show 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@media screen and (max-width: 400px) {
.modal-content {
width: 90%;
}
}

283
images/banner.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -7,14 +7,32 @@
<title>jfa-no</title>
</head>
<body class="max-w-full overflow-x-hidden section">
<div id="login-modal" class="modal">
<form class="modal-content card" id="login-form" href="">
<div id="modal-login" class="modal">
<form class="modal-content card" id="form-login" href="">
<span class="heading">Login</span>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="username" id="login-user">
<input type="password" class="field input ~neutral !high mb-1" placeholder="password" id="login-password">
<input type="submit" class="button ~positive !normal full-width supra submit" value="Login">
</form>
</div>
<div id="modal-add-user" class="modal">
<form class="modal-content card" id="form-add-user" href="">
<span class="heading">New User <span class="modal-close">&times;</span></span>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="username" id="add-user-user">
<input type="password" class="field input ~neutral !high mb-1" placeholder="password" id="add-user-password">
<input type="submit" class="button ~positive !normal full-width supra submit" value="Create">
</form>
</div>
<div id="modal-about" class="modal">
<div class="modal-content content card">
<span class="heading">About <span class="modal-close">&times;</span></span>
<img src="images/banner.svg" class="mt-1" alt="jfa-go banner">
<p><a href="https://github.com/hrfee/jfa-go/tree/a17t-redesign">Github (ICON)</a></p>
<p>Version <span class="code monospace">a17t-redesign</span></p>
<p>Commit <span class="code monospace">cb28097</span></p>
<p><a href="https://github.com/hrfee/jfa-go/blob/main/LICENSE">Available under the MIT License.</a></p>
</div>
</div>
<div class="pageContainer max-w-screen-lg px-6 py-4 mx-auto lg:mx-auto md:py-8">
<div class="relative mb-1">
<header class="flex flex-wrap items-center justify-between">
@ -29,7 +47,7 @@
<div class="text-neutral-700">
<span class="button ~critical !normal mb-1">Logout</span>
<span class="button ~neutral !normal mb-1">Theme</span>
<span id="modalButton" class="button ~neutral !normal mb-1">modalTest</span>
<span id="modalButton" class="button ~neutral !normal mb-1">Trigger Login</span>
</div>
</div>
<div id="invitesTab" class="unfocused">
@ -190,7 +208,7 @@
<div class="row">
<div class="card ~neutral !normal col">
<aside class="aside small ~info mb-half">Note: <sup class="text-critical">*</sup> indicates a required field, <sup class="text-critical">R</sup> indicates changes require a restart.</aside>
<span class="button ~neutral !normal settings-section-button mb-half">About</span>
<span class="button ~neutral !normal settings-section-button mb-half" id="setting-about">About</span>
<span class="button ~neutral !normal settings-section-button mb-half selected">User Profiles</span>
</div>
<div class="card ~neutral !low col">
@ -222,144 +240,7 @@
</div>
</div>
<script>
const whichTransitionEvent = () => {
const el = document.createElement("fakeElement");
if (el.style["animation"] !== void 0) {
return "animationend";
}
return "webkitAnimationEnd";
}
var transitionEnd = whichTransitionEvent();
const toggles = document.getElementsByClassName('toggle-details');
for (let toggle of toggles) {
console.log(toggle);
toggle.onclick = () => {
const el = toggle.parentElement.parentElement.parentElement.nextElementSibling
const container = toggle.parentElement.parentElement.parentElement.parentElement;
if (el.classList.contains("visible")) {
el.classList.toggle("visible");
//el.classList.toggle("hiding");
//const listenerFunc = function(event) { el.classList.toggle("hidden"); el.classList.toggle("hiding"); el.removeEventListener(transitionEnd, listenerFunc); };
el.classList.toggle("hidden");
// el.addEventListener(transitionEnd, listenerFunc, false);
} else {
el.classList.toggle("hidden");
//const height = parseInt(container.clientHeight, 10);
//const val = `${height + el.getBoundingClientRect().height}px`;
//console.log('showing ', val);
//container.style.height = val;
// let maxHeight = container.style.maxHeight || "0";
// const mheight = parseInt(maxHeight, 10)
// container.style.maxHeight = `${mheight + el.getBoundingClientRect().height}px`;
el.classList.toggle("visible");
}
toggle.previousElementSibling.classList.toggle("rotated");
toggle.previousElementSibling.classList.toggle("not-rotated");
//el.classList.toggle("visible");
//el.classList.toggle("hidden");
};
}
const checkInfUses = function (check, mode = 2) {
const uses = document.getElementById('inv-uses');
if (mode == 2) {
uses.disabled = check.checked;
check.parentElement.classList.toggle('!normal');
check.parentElement.classList.toggle('!high');
} else if (mode == 1) {
uses.disabled = true;
check.checked = true;
check.parentElement.classList.remove('!normal');
check.parentElement.classList.add('!high');
} else {
uses.disabled = false;
check.checked = false;
check.parentElement.classList.remove('!high');
check.parentElement.classList.add('!normal');
}
};
let invInfUses = document.getElementById('inv-inf-uses');
invInfUses.onclick = () => { checkInfUses(invInfUses, 2); };
const checkEmailEnabled = function (check, mode = 2) {
const input = document.getElementById('inv-email');
if (mode == 2) {
input.disabled = !check.checked;
check.parentElement.classList.toggle('!normal');
check.parentElement.classList.toggle('!high');
} else if (mode == 1) {
input.disabled = false;
check.checked = true;
check.parentElement.classList.remove('!normal');
check.parentElement.classList.add('!high');
} else {
input.disabled = true;
check.checked = false;
check.parentElement.classList.remove('!high');
check.parentElement.classList.add('!normal');
}
};
let invEmailEnabled = document.getElementById('inv-email-enabled')
invEmailEnabled.onchange = () => { checkEmailEnabled(invEmailEnabled, 2); };
checkInfUses(invInfUses, 0);
checkEmailEnabled(invEmailEnabled, 0);
const loadAccounts = function () {
const rows = document.getElementById("accounts-list").children;
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const editButton = row.querySelector(".icon");
const emailInput = row.querySelector(".input");
editButton.onclick = function () {
emailInput.classList.toggle('stealth-input-hidden');
emailInput.readOnly = !emailInput.readOnly;
editButton.classList.toggle('icon-edit');
editButton.classList.toggle('icon-check');
};
}
};
loadAccounts();
tabs = ["invitesTab", "accountsTab", "settingsTab"]
for (let tab of tabs) {
document.getElementById(`${tab}-button`).onclick = function () {
for (let t of tabs) {
const tabEl = document.getElementById(t);
const tabButtonEl = document.getElementById(`${t}-button`);
if (t == tab) {
tabButtonEl.classList.add("active", "~positive");
tabEl.classList.remove("unfocused");
} else {
tabButtonEl.classList.remove("active");
tabButtonEl.classList.remove("~positive");
tabEl.classList.add("unfocused");
}
}
}
}
function modalToggle(modal) {
if (modal.classList.contains('modal-shown')) {
modal.classList.add('modal-hiding');
let listenerFunc = function () {
modal.classList.remove('modal-shown');
modal.classList.remove('modal-hiding');
modal.removeEventListener(transitionEnd, listenerFunc);
};
modal.addEventListener(transitionEnd, listenerFunc, false);
} else {
modal.classList.add('modal-shown');
}
}
document.getElementById('modalButton').onclick = () => { modalToggle(document.getElementById('login-modal')); };
document.getElementById('login-form').addEventListener('submit', ev => {
ev.preventDefault();
modalToggle(document.getElementById('login-modal'));
});
</script>
<script src="modal.js"></script>
<script src="main.js"></script>
</body>
</html>

110
main.js Normal file
View File

@ -0,0 +1,110 @@
const whichAnimationEvent = () => {
const el = document.createElement("fakeElement");
if (el.style["animation"] !== void 0) {
return "animationend";
}
return "webkitAnimationEnd";
};
window.animationEvent = whichAnimationEvent();
const toggles = Array.from(document.getElementsByClassName("toggle-details"));
for (let toggle of toggles) {
toggle.onclick = () => {
const el = toggle.parentElement.parentElement.parentElement.nextElementSibling;
if (el.classList.contains("visible")) {
el.classList.toggle("visible");
el.classList.toggle("hidden");
} else {
el.classList.toggle("hidden");
el.classList.toggle("visible");
}
toggle.previousElementSibling.classList.toggle("rotated");
toggle.previousElementSibling.classList.toggle("not-rotated");
};
}
const checkInfUses = function(check, mode = 2) {
const uses = document.getElementById("inv-uses");
if (mode == 2) {
uses.disabled = check.checked;
check.parentElement.classList.toggle("!normal");
check.parentElement.classList.toggle("!high");
} else if (mode == 1) {
uses.disabled = true;
check.checked = true;
check.parentElement.classList.remove("!normal");
check.parentElement.classList.add("!high");
} else {
uses.disabled = false;
check.checked = false;
check.parentElement.classList.remove("!high");
check.parentElement.classList.add("!normal");
}
};
let invInfUses = document.getElementById("inv-inf-uses");
invInfUses.onclick = () => {
checkInfUses(invInfUses, 2);
};
const checkEmailEnabled = function(check, mode = 2) {
const input = document.getElementById("inv-email");
if (mode == 2) {
input.disabled = !check.checked;
check.parentElement.classList.toggle("!normal");
check.parentElement.classList.toggle("!high");
} else if (mode == 1) {
input.disabled = false;
check.checked = true;
check.parentElement.classList.remove("!normal");
check.parentElement.classList.add("!high");
} else {
input.disabled = true;
check.checked = false;
check.parentElement.classList.remove("!high");
check.parentElement.classList.add("!normal");
}
};
let invEmailEnabled = document.getElementById("inv-email-enabled");
invEmailEnabled.onchange = () => {
checkEmailEnabled(invEmailEnabled, 2);
};
checkInfUses(invInfUses, 0);
checkEmailEnabled(invEmailEnabled, 0);
const loadAccounts = function() {
const rows = Array.from(document.getElementById("accounts-list").children);
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const editButton = row.querySelector(".icon");
const emailInput = row.querySelector(".input");
editButton.onclick = function() {
emailInput.classList.toggle("stealth-input-hidden");
emailInput.readOnly = !emailInput.readOnly;
editButton.classList.toggle("icon-edit");
editButton.classList.toggle("icon-check");
};
}
};
loadAccounts();
const tabs = ["invitesTab", "accountsTab", "settingsTab"];
for (let tab of tabs) {
document.getElementById(`${tab}-button`).onclick = function() {
for (let t of tabs) {
const tabEl = document.getElementById(t);
const tabButtonEl = document.getElementById(`${t}-button`);
if (t == tab) {
tabButtonEl.classList.add("active", "~positive");
tabEl.classList.remove("unfocused");
} else {
tabButtonEl.classList.remove("active");
tabButtonEl.classList.remove("~positive");
tabEl.classList.add("unfocused");
}
}
};
}
const modalLogin = new Modal(document.getElementById("modal-login"), true);
document.getElementById("form-login").addEventListener("submit", modalLogin.close);
document.getElementById("modalButton").onclick = modalLogin.toggle;
const modalAddUser = new Modal(document.getElementById("modal-add-user"));
document.getElementById("accounts-add-user").onclick = modalAddUser.toggle;
document.getElementById("form-add-user").addEventListener("submit", modalAddUser.close);
const modalAbout = new Modal(document.getElementById("modal-about"));
document.getElementById("setting-about").onclick = modalAbout.toggle;
//# sourceMappingURL=main.js.map

7
main.js.map Normal file

File diff suppressed because one or more lines are too long

62
modal.css Normal file
View File

@ -0,0 +1,62 @@
.modal {
display: none;
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,40%);
}
.modal-shown {
display: block;
}
@keyframes modal-hide {
from { opacity: 1; }
to { opacity: 0; }
}
.modal-hiding {
animation: modal-hide 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@keyframes modal-content-show {
from {
opacity: 0;
top: -6rem;
}
to {
opacity: 1;
top: 0;
}
}
.modal-content {
position: relative;
margin: 10% auto;
width: 30%;
}
.modal-shown .modal-content {
animation: modal-content-show 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@media screen and (max-width: 400px) {
.modal-content {
width: 90%;
}
}
.modal-close {
float: right;
color: #aaa;
font-weight: normal;
}
.modal-close:hover,
.modal-close:focus {
filter: brightness(60%);
}

41
modal.js Normal file
View File

@ -0,0 +1,41 @@
class Modal {
constructor(modal, important = false) {
this.close = (event) => {
if (event) {
event.preventDefault();
}
this.modal.classList.add("modal-hiding");
const modal = this.modal;
const listenerFunc = function() {
modal.classList.remove("modal-shown");
modal.classList.remove("modal-hiding");
modal.removeEventListener(window.animationEvent, listenerFunc);
};
this.modal.addEventListener(window.animationEvent, listenerFunc, false);
};
this.show = () => {
this.modal.classList.add("modal-shown");
};
this.toggle = () => {
if (this.modal.classList.contains("modal-shown")) {
this.close();
} else {
this.show();
}
};
this.modal = modal;
const closeButton = this.modal.querySelector("span.modal-close");
if (closeButton !== null) {
this.closeButton = closeButton;
this.closeButton.onclick = this.close;
}
if (!important) {
window.addEventListener("click", (event) => {
if (event.target == this.modal) {
this.close();
}
});
}
}
}
//# sourceMappingURL=modal.js.map

7
modal.js.map Normal file
View File

@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["ts/modal.ts"],
"sourcesContent": ["declare var window: Window;\n\nclass Modal {\n modal: HTMLDivElement;\n closeButton: HTMLSpanElement;\n constructor(modal: HTMLDivElement, important: boolean = false) {\n this.modal = modal;\n const closeButton = this.modal.querySelector('span.modal-close')\n if (closeButton !== null) {\n this.closeButton = closeButton as HTMLSpanElement;\n this.closeButton.onclick = this.close;\n }\n if (!important) {\n window.addEventListener('click', (event: Event) => {\n if (event.target == this.modal) { this.close(); }\n });\n }\n }\n close = (event?: Event) => {\n if (event) {\n event.preventDefault();\n }\n this.modal.classList.add('modal-hiding');\n const modal = this.modal;\n const listenerFunc = function () {\n modal.classList.remove('modal-shown');\n modal.classList.remove('modal-hiding');\n modal.removeEventListener(window.animationEvent, listenerFunc);\n };\n this.modal.addEventListener(window.animationEvent, listenerFunc, false);\n }\n show = () => {\n this.modal.classList.add('modal-shown');\n }\n toggle = () => {\n if (this.modal.classList.contains('modal-shown')) {\n this.close();\n } else {\n this.show();\n }\n }\n}\n"],
"mappings": "AAAA;AAAA,EAKI,YAAY,mBAA4C;AAaxD,iBAAQ;AACJ,UAAI;AACA,cAAM;AAAA;AAEV,WAAK,MAAM,UAAU,IAAI;AACzB,oBAAc,KAAK;AACnB,2BAAqB;AACjB,cAAM,UAAU,OAAO;AACvB,cAAM,UAAU,OAAO;AACvB,cAAM,oBAAoB,OAAO,gBAAgB;AAAA;AAErD,WAAK,MAAM,iBAAiB,OAAO,gBAAgB,cAAc;AAAA;AAErE,gBAAO;AACH,WAAK,MAAM,UAAU,IAAI;AAAA;AAE7B,kBAAS;AACL,UAAI,KAAK,MAAM,UAAU,SAAS;AAC9B,aAAK;AAAA;AAEL,aAAK;AAAA;AAAA;AAhCT,SAAK,QAAQ;AACb,wBAAoB,KAAK,MAAM,cAAc;AAC7C,QAAI,gBAAgB;AAChB,WAAK,cAAc;AACnB,WAAK,YAAY,UAAU,KAAK;AAAA;AAEpC,QAAI,CAAC;AACD,aAAO,iBAAiB,SAAS;AAC7B,YAAI,MAAM,UAAU,KAAK;AAAS,eAAK;AAAA;AAAA;AAAA;AAAA;AAAA;",
"names": []
}

127
ts/main.ts Normal file
View File

@ -0,0 +1,127 @@
interface Window {
transitionEvent: string;
animationEvent: string;
}
interface ArrayConstructor {
from(arrayLike: any, mapFn?, thisArg?): Array<any>;
}
declare var window: Window;
const whichAnimationEvent = () => {
const el = document.createElement("fakeElement");
if (el.style["animation"] !== void 0) {
return "animationend";
}
return "webkitAnimationEnd";
}
window.animationEvent = whichAnimationEvent();
const toggles: HTMLInputElement[] = Array.from(document.getElementsByClassName('toggle-details'));
for (let toggle of toggles) {
toggle.onclick = () => {
const el = toggle.parentElement.parentElement.parentElement.nextElementSibling as HTMLDivElement;
if (el.classList.contains("visible")) {
el.classList.toggle("visible");
el.classList.toggle("hidden");
} else {
el.classList.toggle("hidden");
el.classList.toggle("visible");
}
toggle.previousElementSibling.classList.toggle("rotated");
toggle.previousElementSibling.classList.toggle("not-rotated");
};
}
const checkInfUses = function (check: HTMLInputElement, mode = 2) {
const uses = document.getElementById('inv-uses') as HTMLInputElement;
if (mode == 2) {
uses.disabled = check.checked;
check.parentElement.classList.toggle('!normal');
check.parentElement.classList.toggle('!high');
} else if (mode == 1) {
uses.disabled = true;
check.checked = true;
check.parentElement.classList.remove('!normal');
check.parentElement.classList.add('!high');
} else {
uses.disabled = false;
check.checked = false;
check.parentElement.classList.remove('!high');
check.parentElement.classList.add('!normal');
}
};
let invInfUses = document.getElementById('inv-inf-uses') as HTMLInputElement;
invInfUses.onclick = () => { checkInfUses(invInfUses, 2); };
const checkEmailEnabled = function (check: HTMLInputElement, mode = 2) {
const input = document.getElementById('inv-email') as HTMLInputElement;
if (mode == 2) {
input.disabled = !check.checked;
check.parentElement.classList.toggle('!normal');
check.parentElement.classList.toggle('!high');
} else if (mode == 1) {
input.disabled = false;
check.checked = true;
check.parentElement.classList.remove('!normal');
check.parentElement.classList.add('!high');
} else {
input.disabled = true;
check.checked = false;
check.parentElement.classList.remove('!high');
check.parentElement.classList.add('!normal');
}
};
let invEmailEnabled = document.getElementById('inv-email-enabled') as HTMLInputElement;
invEmailEnabled.onchange = () => { checkEmailEnabled(invEmailEnabled, 2); };
checkInfUses(invInfUses, 0);
checkEmailEnabled(invEmailEnabled, 0);
const loadAccounts = function () {
const rows: HTMLTableRowElement[] = Array.from(document.getElementById("accounts-list").children);
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const editButton = row.querySelector(".icon") as HTMLElement;
const emailInput = row.querySelector(".input") as HTMLInputElement;
editButton.onclick = function () {
emailInput.classList.toggle('stealth-input-hidden');
emailInput.readOnly = !emailInput.readOnly;
editButton.classList.toggle('icon-edit');
editButton.classList.toggle('icon-check');
};
}
};
loadAccounts();
const tabs = ["invitesTab", "accountsTab", "settingsTab"]
for (let tab of tabs) {
(document.getElementById(`${tab}-button`) as HTMLSpanElement).onclick = function () {
for (let t of tabs) {
const tabEl = document.getElementById(t) as HTMLDivElement;
const tabButtonEl = document.getElementById(`${t}-button`) as HTMLSpanElement;
if (t == tab) {
tabButtonEl.classList.add("active", "~positive");
tabEl.classList.remove("unfocused");
} else {
tabButtonEl.classList.remove("active");
tabButtonEl.classList.remove("~positive");
tabEl.classList.add("unfocused");
}
}
}
}
const modalLogin = new Modal(document.getElementById('modal-login'), true);
document.getElementById('form-login').addEventListener('submit', modalLogin.close);
document.getElementById('modalButton').onclick = modalLogin.toggle;
const modalAddUser = new Modal(document.getElementById('modal-add-user'));
(document.getElementById('accounts-add-user') as HTMLSpanElement).onclick = modalAddUser.toggle;
document.getElementById('form-add-user').addEventListener('submit', modalAddUser.close);
const modalAbout = new Modal(document.getElementById('modal-about'));
(document.getElementById('setting-about') as HTMLSpanElement).onclick = modalAbout.toggle;

42
ts/modal.ts Normal file
View File

@ -0,0 +1,42 @@
declare var window: Window;
class Modal {
modal: HTMLDivElement;
closeButton: HTMLSpanElement;
constructor(modal: HTMLDivElement, important: boolean = false) {
this.modal = modal;
const closeButton = this.modal.querySelector('span.modal-close')
if (closeButton !== null) {
this.closeButton = closeButton as HTMLSpanElement;
this.closeButton.onclick = this.close;
}
if (!important) {
window.addEventListener('click', (event: Event) => {
if (event.target == this.modal) { this.close(); }
});
}
}
close = (event?: Event) => {
if (event) {
event.preventDefault();
}
this.modal.classList.add('modal-hiding');
const modal = this.modal;
const listenerFunc = function () {
modal.classList.remove('modal-shown');
modal.classList.remove('modal-hiding');
modal.removeEventListener(window.animationEvent, listenerFunc);
};
this.modal.addEventListener(window.animationEvent, listenerFunc, false);
}
show = () => {
this.modal.classList.add('modal-shown');
}
toggle = () => {
if (this.modal.classList.contains('modal-shown')) {
this.close();
} else {
this.show();
}
}
}