mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-11-09 20:00:12 +00:00
576 lines
25 KiB
HTML
576 lines
25 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<link rel="stylesheet" type="text/css" href="node_modules/a17t/dist/a17t.css">
|
|
<link rel="stylesheet" type="text/css" href="node_modules/icons.css/dist/icons.css">
|
|
<style>
|
|
.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;
|
|
}
|
|
|
|
</style>
|
|
<title>{{ .lang.pageTitle }}</title>
|
|
</head>
|
|
<body class="max-w-full overflow-x-hidden section">
|
|
<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">
|
|
<div class="text-neutral-700">
|
|
<span id="invitesTab-button" class="tabText portal ~positive active">Invites</span>
|
|
<span id="accountsTab-button" class="tabText portal">Accounts</span>
|
|
<span id="settingsTab-button" class="tabText portal">Settings</span>
|
|
</div>
|
|
</header>
|
|
</div>
|
|
<div class="relative mb-1">
|
|
<div class="text-neutral-700">
|
|
<span class="button ~critical !normal mb-1">Logout</span>
|
|
<span class="button ~neutral !normal mb-1">Theme</span>
|
|
</div>
|
|
</div>
|
|
<div id="invitesTab" class="unfocused">
|
|
<div class="card ~neutral !high invites mb-1">
|
|
<span class="heading">Invites</span>
|
|
<div class="inv">
|
|
<div class="card ~neutral !normal inv-header mt-half">
|
|
<div class="inv-codearea">
|
|
<a href="#" class="code monospace mr-1">ZD8ZeC55Jcpmbtv54FuVM3</a>
|
|
<span class="button ~info !normal">Copy</span>
|
|
</div>
|
|
<div class="inv-infoarea">
|
|
<span class="inv-expiry mr-1">Expires in 30m</span>
|
|
<span class="button ~critical !normal">Delete</span>
|
|
<label>
|
|
<i class="icon icon-arrow-down not-rotated"></i>
|
|
<input type="checkbox" class="toggle-details">
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="card ~neutral !normal mt-half inv-details mt-half hidden">
|
|
<div class="inv-row">
|
|
<div class="inv-profilearea">
|
|
<p class="supra mb-1">Profile</p>
|
|
<div class="select ~neutral !normal inv-profileselect ib">
|
|
<select>
|
|
<option>Friends</option>
|
|
<option>Family</option>
|
|
<option>No Profile</option>
|
|
</select>
|
|
</div>
|
|
<p class="label supra">Notify on:</p>
|
|
<label class="switch block">
|
|
<input type="checkbox" class="inv-notify-expiry">
|
|
<span>On expiry</span>
|
|
</label>
|
|
<label class="switch block">
|
|
<input type="checkbox" class="inv-notify-creation">
|
|
<span>On user creation</span>
|
|
</label>
|
|
</div>
|
|
<div class="block">
|
|
<p class="supra mb-1">Created <strong class="inv-created">10/12/20 18:46</strong></p>
|
|
<p class="supra mb-1">Remaining uses <strong class="inv-remaining">8</strong></p>
|
|
</div>
|
|
<div class="card ~neutral !low">
|
|
<strong class="supra table-header">Created users</strong>
|
|
<table class="table inv-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Date</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>jeff</td>
|
|
<td>10/12/20 19:00</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card ~neutral !high create-inv">
|
|
<span class="heading">Create</span>
|
|
<div class="row">
|
|
<div class="card ~neutral !low col">
|
|
<label class="label supra" for="inv-days">Days</label>
|
|
<div class="select ~neutral !normal mb-1">
|
|
<select id="inv-days">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="inv-hours">Hours</label>
|
|
<div class="select ~neutral !normal mb-1">
|
|
<select id="inv-hours">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="inv-minutes">Minutes</label>
|
|
<div class="select ~neutral !normal mb-1">
|
|
<select id="inv-minutes">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="card ~neutral !low col">
|
|
<label class="label supra" for="inv-uses">Number of uses</label>
|
|
<div class="button-input mb-1">
|
|
<input type="number" min="0" id="inv-uses" class="input ~neutral !normal mr-1" value=1>
|
|
<label for="inv-inf-uses" class="button ~neutral !normal">
|
|
<span>∞</span>
|
|
<input type="checkbox" class="unfocused" id="inv-inf-uses" aria-label="Set uses to infinite">
|
|
</label>
|
|
</div>
|
|
<label class="label supra">Profile</label>
|
|
<div class="select ~neutral !normal mb-1" id="inv-profile">
|
|
<select>
|
|
<option>Friends</option>
|
|
<option>Family</option>
|
|
<option>No Profile</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra">Send to</label>
|
|
<div class="button-input mb-1">
|
|
<input type="text" id="inv-email" class="input ~neutral !normal mr-1" placeholder="example@example.com">
|
|
<label for="inv-email-enabled" class="button ~neutral !normal">
|
|
<input type="checkbox" id="inv-email-enabled" aria-label="Send to address enabled">
|
|
</label>
|
|
</div>
|
|
<span class="button ~positive !normal supra full-width button-lg">Create</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="accountsTab" class="unfocused">
|
|
<div class="card ~neutral !high accounts mb-1">
|
|
<span class="heading">Accounts</span>
|
|
<div class="fr">
|
|
<span class="button ~neutral !normal" id="accounts-add-user">Add User</span>
|
|
<span class="button ~positive !normal" id="accounts-modify-user">Modify Settings</span>
|
|
<span class="button ~critical !normal" id="accounts-delte-user">Delete User</span>
|
|
</div>
|
|
<div class="card ~neutral !normal accounts-header mt-half">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th><input type="checkbox" value="" id="accounts-select-all"></th>
|
|
<th>Username</th>
|
|
<th>Email Address</th>
|
|
<th>Last Active</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="accounts-list">
|
|
<tr>
|
|
<td><input type="checkbox" value=""></td>
|
|
<td>Person <span class="chip ~info ml-1">Admin</span></td>
|
|
<td><i class="icon icon-edit"></i><input type="email" class="input ~neutral !normal stealth-input stealth-input-hidden" value="email@addr.ess" readonly></td>
|
|
<td>13/12/20 00:39</td>
|
|
</tr>
|
|
<tr>
|
|
<td><input type="checkbox" value=""></td>
|
|
<td>Other person</td>
|
|
<td><i class="icon icon-edit"></i><input type="email" class="input ~neutral !normal stealth-input stealth-input-hidden" value="eee@ma.il" readonly></td>
|
|
<td>12/12/20 17:46</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="settingsTab">
|
|
<div class="card ~neutral !high settings">
|
|
<span class="heading">Settings</span>
|
|
<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 selected">User Profiles</span>
|
|
</div>
|
|
<div class="card ~neutral !low col">
|
|
<div class="settings-section">
|
|
<p class="support large mb-half">Settings section description.</p>
|
|
<div class="setting">
|
|
<label class="label" for="settings-select">Select <sup class="text-critical">R</sup></label>
|
|
<div class="select ~neutral !normal mt-half">
|
|
<select id="settings-select">
|
|
<option>Option 1</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="setting">
|
|
<label class="label" for="settings-input">Input <sup class="text-critical">*</sup></label>
|
|
<input type="text" class="input ~neutral !normal mt-half" placeholder="Value">
|
|
</div>
|
|
<div class="setting">
|
|
<label class="switch settings">
|
|
<input type="checkbox" id="settings-check">
|
|
<span>Checkbox <sup class="text-critical">R</sup></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</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");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|