mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 17:10:10 +00:00
Harvey Tindall
66b7df7cde
You can now choose between 12h and 24h time in the top left language menu. Your preference is stored by the browser for future visits.
466 lines
28 KiB
HTML
466 lines
28 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" class="{{ .cssClass }}">
|
|
<head>
|
|
<link rel="stylesheet" type="text/css" href="{{ .urlBase }}/css/bundle.css">
|
|
<script>
|
|
window.URLBase = "{{ .urlBase }}";
|
|
window.notificationsEnabled = {{ .notifications }};
|
|
window.emailEnabled = {{ .email_enabled }};
|
|
window.ombiEnabled = {{ .ombiEnabled }};
|
|
window.usernameEnabled = {{ .username }};
|
|
window.langFile = JSON.parse({{ .language }});
|
|
window.language = "{{ .langName }}";
|
|
</script>
|
|
{{ template "header.html" . }}
|
|
<title>Admin - jfa-go</title>
|
|
</head>
|
|
<body class="max-w-full overflow-x-hidden section">
|
|
<div id="modal-login" class="modal">
|
|
<form class="modal-content card" id="form-login" href="">
|
|
<span class="heading">{{ .strings.login }}</span>
|
|
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="login-user">
|
|
<input type="password" class="field input ~neutral !high mb-1" placeholder="{{ .strings.password }}" id="login-password">
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~urge !normal full-width center supra submit">{{ .strings.login }}</span>
|
|
</label>
|
|
</form>
|
|
</div>
|
|
<div id="modal-add-user" class="modal">
|
|
<form class="modal-content card" id="form-add-user" href="">
|
|
<span class="heading">{{ .strings.newUser }} <span class="modal-close">×</span></span>
|
|
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="add-user-user">
|
|
<input type="email" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.emailAddress }}">
|
|
<input type="password" class="field input ~neutral !high mb-1" placeholder="{{ .strings.password }}" id="add-user-password">
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~urge !normal full-width center supra submit">{{ .strings.create }}</span>
|
|
</label>
|
|
</form>
|
|
</div>
|
|
<div id="modal-about" class="modal">
|
|
<div class="modal-content content card">
|
|
<img src="{{ .urlBase }}/banner.svg" class="banner header" alt="jfa-go banner">
|
|
<span class="heading"><span class="modal-close">×</span></span>
|
|
<p><i class="icon ri-github-fill"></i><a href="https://github.com/hrfee/jfa-go">jfa-go</a></p>
|
|
<p>{{ .strings.version }} <span class="code monospace">{{ .version }}</span></p>
|
|
<p>{{ .strings.commitNoun }} <span class="code monospace">{{ .commit }}</span></p>
|
|
<p><a href="https://github.com/hrfee/jfa-go/blob/main/LICENSE">Available under the MIT License.</a></p>
|
|
<pre class="monospace">{{ .license }}</pre>
|
|
</div>
|
|
</div>
|
|
<div id="modal-modify-user" class="modal">
|
|
<form class="modal-content card" id="form-modify-user" href="">
|
|
<span class="heading"><span id="header-modify-user"></span> <span class="modal-close">×</span></span>
|
|
<p class="content">{{ .strings.modifySettingsDescription }}</p>
|
|
<div class="flex-row mb-1">
|
|
<label class="flex-row-group mr-1">
|
|
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-profile" checked>
|
|
<span class="button ~neutral !high supra full-width center">{{ .strings.profile }}</span>
|
|
</label>
|
|
<label class="flex-row-group ml-1">
|
|
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-user">
|
|
<span class="button ~neutral !normal supra full-width center">{{ .strings.user }}</span>
|
|
</label>
|
|
</div>
|
|
<div class="select ~neutral !normal mb-1">
|
|
<select id="modify-user-profiles"></select>
|
|
</div>
|
|
<div class="select ~neutral !normal mb-1 unfocused">
|
|
<select id="modify-user-users"></select>
|
|
</div>
|
|
<label class="switch mb-1">
|
|
<input type="checkbox" id="modify-user-homescreen" checked>
|
|
<span>{{ .strings.applyHomescreenLayout }}</span>
|
|
</label>
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~urge !normal full-width center supra submit">{{ .strings.apply }}</span>
|
|
</label>
|
|
</form>
|
|
</div>
|
|
<div id="modal-delete-user" class="modal">
|
|
<form class="modal-content card" id="form-delete-user" href="">
|
|
<span class="heading"><span id="header-delete-user"></span> <span class="modal-close">×</span></span>
|
|
<div class="content mt-half">
|
|
<label class="switch mb-1">
|
|
<input type="checkbox" id="delete-user-notify" checked>
|
|
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
|
|
</label>
|
|
<textarea id="textarea-delete-user" class="textarea full-width ~neutral !normal mb-1" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~critical !normal full-width center supra submit">{{ .strings.delete }}</span>
|
|
</label>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div id="modal-extend-expiry" class="modal">
|
|
<form class="modal-content card" id="form-extend-expiry" href="">
|
|
<span class="heading"><span id="header-extend-expiry"></span> <span class="modal-close">×</span></span>
|
|
<div class="content mt-half">
|
|
<label class="label supra" for="extend-expiry-days">{{ .strings.inviteDays }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="extend-expiry-days">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="extend-expiry-hours">{{ .strings.inviteHours }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="extend-expiry-hours">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="extend-expiry-minutes">{{ .strings.inviteMinutes }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="extend-expiry-minutes">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~critical !normal full-width center supra submit">{{ .strings.submit }}</span>
|
|
</label>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div id="modal-announce" class="modal">
|
|
<form class="modal-content card" id="form-announce" href="">
|
|
<span class="heading"><span id="header-announce"></span> <span class="modal-close">×</span></span>
|
|
<div class="content mt-half">
|
|
<label class="label supra" for="announce-subject"> {{ .strings.subject }}</label>
|
|
<input type="text" id="announce-subject" class="input ~neutral !normal mb-1 mt-half">
|
|
<label class="label supra" for="textarea-announce">{{ .strings.message }}</label>
|
|
<textarea id="textarea-announce" class="textarea full-width ~neutral !normal mt-half monospace"></textarea>
|
|
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
|
</label>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div id="modal-customize" class="modal">
|
|
<div class="modal-content card">
|
|
<span class="heading">{{ .strings.customizeEmails }} <span class="modal-close">×</span></span>
|
|
<p class="content">{{ .strings.customizeEmailsDescription }}</p>
|
|
<div class="table-responsive">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>{{ .strings.name }}</th>
|
|
<th>{{ .strings.reset }}</th>
|
|
<th>{{ .strings.edit }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="customize-list"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="modal-editor" class="modal">
|
|
<form class="modal-content wide card" id="form-editor" href="">
|
|
<span class="heading"><span id="header-editor"></span> <span class="modal-close">×</span></span>
|
|
<div class="row">
|
|
<div class="col flex-col content mt-half">
|
|
<span class="label supra" for="editor-variables" id="label-editor-variables">{{ .strings.variables }}</span>
|
|
<div id="editor-variables"></div>
|
|
<label class="label supra" for="textarea-editor">{{ .strings.message }}</label>
|
|
<textarea id="textarea-editor" class="textarea full-width flex-auto ~neutral !normal mt-half monospace"></textarea>
|
|
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
|
<div class="flex-row">
|
|
<label class="full-width ml-half">
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col card ~neutral !low">
|
|
<span class="subheading supra">{{ .strings.preview }}</span>
|
|
<div class="mt-half" id="editor-preview"></div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div id="modal-restart" class="modal">
|
|
<div class="modal-content card ~critical !low">
|
|
<span class="heading">{{ .strings.settingsRestartRequired }} <span class="modal-close">×</span></span>
|
|
<p class="content pb-1">{{ .strings.settingsRestartRequiredDescription }}</p>
|
|
<div class="fr">
|
|
<span class="button ~info !normal mb-half" id="settings-apply-no-restart">{{ .strings.settingsApplyRestartLater }}</span>
|
|
<span class="button ~critical !normal" id="settings-apply-restart">{{ .strings.settingsApplyRestartNow }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="modal-refresh" class="modal">
|
|
<div class="modal-content card ~neutral !normal">
|
|
<span class="heading">{{ .strings.settingsApplied }}</span>
|
|
<p class="content">{{ .strings.settingsRefreshPage }}</p>
|
|
</div>
|
|
</div>
|
|
<div id="modal-ombi-defaults" class="modal">
|
|
<form class="modal-content card" id="form-ombi-defaults" href="">
|
|
<span class="heading">{{ .strings.ombiUserDefaults }} <span class="modal-close">×</span></span>
|
|
<p class="content">{{ .strings.ombiUserDefaultsDescription }}</p>
|
|
<div class="select ~neutral !normal mb-1">
|
|
<select></select>
|
|
</div>
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
|
</label>
|
|
</form>
|
|
</div>
|
|
<div id="modal-user-profiles" class="modal">
|
|
<div class="modal-content wide card">
|
|
<span class="heading">{{ .strings.userProfiles }} <span class="modal-close">×</span></span>
|
|
<p class="support lg">{{ .strings.userProfilesDescription }}</p>
|
|
<div class="table-responsive">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>{{ .strings.name }}</th>
|
|
<th>{{ .strings.userProfilesIsDefault }}</th>
|
|
<th>{{ .strings.from }}</th>
|
|
<th>{{ .strings.userProfilesLibraries }}</th>
|
|
<th><span class="button ~neutral !high" id="button-profile-create">{{ .strings.create }}</span></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table-profiles"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="modal-add-profile" class="modal">
|
|
<form class="modal-content card" id="form-add-profile" href="">
|
|
<span class="heading">{{ .strings.addProfile }} <span class="modal-close">×</span></span>
|
|
<p class="content">{{ .strings.addProfileDescription }}</p>
|
|
<label>
|
|
<span class="supra">{{ .strings.addProfileNameOf }} </span>
|
|
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.name }}" id="add-profile-name">
|
|
<label>
|
|
<span class="supra">{{ .strings.user }}</span>
|
|
<div class="select ~neutral !normal mt-half mb-1">
|
|
<select id="add-profile-user"></select>
|
|
</div>
|
|
</label>
|
|
<label class="switch mb-1">
|
|
<input type="checkbox" id="add-profile-homescreen" checked>
|
|
<span>{{ .strings.addProfileStoreHomescreenLayout }}</span>
|
|
</label>
|
|
<label>
|
|
<input type="submit" class="unfocused">
|
|
<span class="button ~urge !normal full-width center supra submit">{{ .strings.create }}</span>
|
|
</label>
|
|
</form>
|
|
</div>
|
|
<div id="modal-update" class="modal">
|
|
<div class="modal-content wide card">
|
|
<span class="heading">{{ .strings.updates }} <span class="modal-close">×</span></span>
|
|
<p class="content">
|
|
<h2>
|
|
<a id="update-version"></a> (<span class="monospace" id="update-commit"></span>)
|
|
</h2>
|
|
<p class="content" id="update-description"></p>
|
|
<p class="support" id="update-date"></p>
|
|
<div class="content markdown-box" id="update-changelog"></div>
|
|
</p>
|
|
<span class="button ~info !normal full-width center" id="update-download">{{ .strings.download }}</span>
|
|
<span class="button ~urge !normal full-width center" id="update-update">{{ .strings.update }}</span>
|
|
</div>
|
|
</div>
|
|
<div id="notification-box"></div>
|
|
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
|
<span class="button ~urge dropdown-button">
|
|
<i class="ri-global-line"></i>
|
|
<span class="ml-1 chev"></span>
|
|
</span>
|
|
<div class="dropdown-display">
|
|
<div class="card ~neutral !low">
|
|
<label class="switch pb-1">
|
|
<input type="radio" name="lang-time" id="lang-12h">
|
|
<span>{{ .strings.time12h }}</span>
|
|
</label>
|
|
<label class="switch pb-1">
|
|
<input type="radio" name="lang-time" id="lang-24h">
|
|
<span>{{ .strings.time24h }}</span>
|
|
</label>
|
|
<div id="lang-list"></div>
|
|
</div>
|
|
</div>
|
|
</span>
|
|
<div class="page-container">
|
|
<div class="mb-1">
|
|
<header class="flex flex-wrap items-center justify-between">
|
|
<div class="text-neutral-700">
|
|
<span id="button-tab-invites" class="tab-button portal">{{ .strings.invites }}</span>
|
|
<span id="button-tab-accounts" class="tab-button portal">{{ .strings.accounts }}</span>
|
|
<span id="button-tab-settings" class="tab-button portal">{{ .strings.settings }}</span>
|
|
</div>
|
|
</header>
|
|
</div>
|
|
<div class="mb-1">
|
|
<div class="text-neutral-700">
|
|
<span class="button ~critical !normal mb-1 unfocused" id="logout-button">{{ .strings.logout }}</span>
|
|
<span id="button-theme" class="button ~neutral !normal mb-1">{{ .strings.theme }}</span>
|
|
</div>
|
|
</div>
|
|
<div id="tab-invites">
|
|
<div class="card ~neutral !low invites mb-1">
|
|
<span class="heading">{{ .strings.invites }}</span>
|
|
<div id="invites"></div>
|
|
</div>
|
|
<div class="card ~neutral !low">
|
|
<span class="heading">{{ .strings.create }}</span>
|
|
<div class="row" id="create-inv">
|
|
<div class="card ~neutral !normal col">
|
|
<div class="row mb-1">
|
|
<label class="col mr-1">
|
|
<input type="radio" name="duration" class="unfocused" id="radio-inv-duration" checked>
|
|
<span class="button ~neutral !high supra full-width center">{{ .strings.inviteDuration }}</span>
|
|
</label>
|
|
<label class="col ml-1">
|
|
<input type="radio" name="duration" class="unfocused" id="radio-user-expiry">
|
|
<span class="button ~neutral !normal supra full-width center">{{ .strings.userExpiry }}</span>
|
|
</label>
|
|
</div>
|
|
<div id="inv-duration">
|
|
<label class="label supra" for="create-days">{{ .strings.inviteDays }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="create-days">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="create-hours">{{ .strings.inviteHours }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="create-hours">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="create-minutes">{{ .strings.inviteMinutes }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="create-minutes">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div id="user-expiry" class="unfocused">
|
|
<p class="support">{{ .strings.userExpiryDescription }}</p>
|
|
<div class="mb-half">
|
|
<label for="create-user-expiry-enabled" class="button ~neutral !normal">
|
|
<input type="checkbox" id="create-user-expiry-enabled" aria-label="User duration enabled">
|
|
<span class="ml-half">{{ .strings.enabled }} </span>
|
|
</label>
|
|
</div>
|
|
<label class="label supra" for="user-days">{{ .strings.inviteDays }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="user-days">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="user-hours">{{ .strings.inviteHours }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="user-hours">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
<label class="label supra" for="user-minutes">{{ .strings.inviteMinutes }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="user-minutes">
|
|
<option>0</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<label class="label supra" for="create-label"> {{ .strings.label }}</label>
|
|
<input type="text" id="create-label" class="input ~neutral !normal mb-1 mt-half">
|
|
</div>
|
|
<div class="card ~neutral !normal col">
|
|
<label class="label supra" for="create-uses">{{ .strings.inviteNumberOfUses }}</label>
|
|
<div class="flex-expand mb-1 mt-half">
|
|
<input type="number" min="0" id="create-uses" class="input ~neutral !normal mr-1" value=1>
|
|
<label for="create-inf-uses" class="button ~neutral !normal" title="Set uses to infinite">
|
|
<span>∞</span>
|
|
<input type="checkbox" class="unfocused" id="create-inf-uses" aria-label="Set uses to infinite">
|
|
</label>
|
|
</div>
|
|
<p class="support unfocused" id="create-inf-uses-warning"><span class="badge ~critical">{{ .strings.warning }}</span> {{ .strings.inviteInfiniteUsesWarning }}</p>
|
|
<label class="label supra">{{ .strings.profile }}</label>
|
|
<div class="select ~neutral !normal mb-1 mt-half">
|
|
<select id="create-profile">
|
|
</select>
|
|
</div>
|
|
<div id="create-send-to-container">
|
|
<label class="label supra">{{ .strings.inviteSendToEmail }}</label>
|
|
<div class="flex-expand mb-1 mt-half">
|
|
<input type="email" id="create-send-to" class="input ~neutral !normal mr-1" placeholder="example@example.com">
|
|
<label for="create-send-to-enabled" class="button ~neutral !normal">
|
|
<input type="checkbox" id="create-send-to-enabled" aria-label="Send to address enabled">
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<span class="button ~urge !normal supra full-width center lg" id="create-submit">{{ .strings.create }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="tab-accounts" class="unfocused">
|
|
<div class="card ~neutral !low accounts mb-1">
|
|
<div class="flex-expand row">
|
|
<div class="row">
|
|
<span class="heading mr-1 col sm">{{ .strings.accounts }}</span>
|
|
<input type="search" class="col sm field ~neutral !normal input search ml-1 mr-1" id="accounts-search" placeholder="{{ .strings.search }}">
|
|
</div>
|
|
<div class="row">
|
|
<span class="col sm button ~neutral !normal center mb-half" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
|
<span class="col sm button ~info !normal center mb-half" id="accounts-announce">{{ .strings.announce }}</span>
|
|
<span class="col sm button ~urge !normal center mb-half" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
|
<span class="col sm button ~warning !normal center mb-half" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
|
<span class="col sm button ~critical !normal center mb-half" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="card ~neutral !normal accounts-header table-responsive mt-half">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th><input type="checkbox" value="" id="accounts-select-all"></th>
|
|
<th>{{ .strings.username }}</th>
|
|
<th>{{ .strings.emailAddress }}</th>
|
|
<th>{{ .strings.expiry }}</th>
|
|
<th>{{ .strings.lastActiveTime }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="accounts-list"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="tab-settings" class="unfocused">
|
|
<div class="card ~neutral !low settings overflow">
|
|
<div class="flex-expand">
|
|
<div class="flex-row">
|
|
<span class="heading">{{ .strings.settings }}</span>
|
|
<label for="settings-advanced-enabled" class="button ~neutral !normal ml-1">
|
|
<input type="checkbox" id="settings-advanced-enabled" aria-label="Advanced settings enabled">
|
|
<span class="ml-half">{{ .strings.advancedSettings }} </span>
|
|
</label>
|
|
</div>
|
|
<div>
|
|
<span class="button ~neutral !normal" id="settings-restart">{{ .strings.settingsRestart }}</span>
|
|
<span class="button ~urge !normal unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="card ~neutral !normal col" id="settings-sidebar">
|
|
<aside class="aside sm ~info mb-half" id="settings-message">Note: <span class="badge ~critical">*</span> indicates a required field, <span class="badge ~info">R</span> indicates changes require a restart.</aside>
|
|
<span class="button ~neutral !low settings-section-button mb-half" id="setting-about"><span class="flex">{{ .strings.aboutProgram }} <i class="ri-information-line ml-half"></i></span></span>
|
|
<span class="button ~neutral !low settings-section-button mb-half" id="setting-profiles"><span class="flex">{{ .strings.userProfiles }} <i class="ri-user-line ml-half"></i></span></span>
|
|
</div>
|
|
<div class="card ~neutral !normal col overflow" id="settings-panel"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script src="{{ .urlBase }}/js/admin.js" type="module"></script>
|
|
</body>
|
|
</html>
|