mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-28 03:50:10 +00:00
organise code, use typescript, add more modals
This commit is contained in:
parent
cb280975b7
commit
e50a7948e7
279
2
279
2
@ -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%;
|
|
||||||
}
|
|
||||||
}
|
|
53
base.css
53
base.css
@ -1,3 +1,5 @@
|
|||||||
|
@import "modal.css";
|
||||||
|
|
||||||
.pageContainer {
|
.pageContainer {
|
||||||
margin: 5% 20% 5% 20%;
|
margin: 5% 20% 5% 20%;
|
||||||
}
|
}
|
||||||
@ -240,54 +242,3 @@ input[type=number] {
|
|||||||
font-size: 1rem;
|
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
283
images/banner.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 58 KiB |
167
index.html
167
index.html
@ -7,14 +7,32 @@
|
|||||||
<title>jfa-no</title>
|
<title>jfa-no</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="max-w-full overflow-x-hidden section">
|
<body class="max-w-full overflow-x-hidden section">
|
||||||
<div id="login-modal" class="modal">
|
<div id="modal-login" class="modal">
|
||||||
<form class="modal-content card" id="login-form" href="">
|
<form class="modal-content card" id="form-login" href="">
|
||||||
<span class="heading">Login</span>
|
<span class="heading">Login</span>
|
||||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="username" id="login-user">
|
<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="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">
|
<input type="submit" class="button ~positive !normal full-width supra submit" value="Login">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</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">×</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">×</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="pageContainer max-w-screen-lg px-6 py-4 mx-auto lg:mx-auto md:py-8">
|
||||||
<div class="relative mb-1">
|
<div class="relative mb-1">
|
||||||
<header class="flex flex-wrap items-center justify-between">
|
<header class="flex flex-wrap items-center justify-between">
|
||||||
@ -29,7 +47,7 @@
|
|||||||
<div class="text-neutral-700">
|
<div class="text-neutral-700">
|
||||||
<span class="button ~critical !normal mb-1">Logout</span>
|
<span class="button ~critical !normal mb-1">Logout</span>
|
||||||
<span class="button ~neutral !normal mb-1">Theme</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>
|
</div>
|
||||||
<div id="invitesTab" class="unfocused">
|
<div id="invitesTab" class="unfocused">
|
||||||
@ -190,7 +208,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="card ~neutral !normal col">
|
<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>
|
<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>
|
<span class="button ~neutral !normal settings-section-button mb-half selected">User Profiles</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="card ~neutral !low col">
|
<div class="card ~neutral !low col">
|
||||||
@ -222,144 +240,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script src="modal.js"></script>
|
||||||
const whichTransitionEvent = () => {
|
<script src="main.js"></script>
|
||||||
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>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
110
main.js
Normal file
110
main.js
Normal 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
7
main.js.map
Normal file
File diff suppressed because one or more lines are too long
62
modal.css
Normal file
62
modal.css
Normal 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
41
modal.js
Normal 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
7
modal.js.map
Normal 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
127
ts/main.ts
Normal 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
42
ts/modal.ts
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user