1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-22 15:20:09 +01:00

Removed a tons of files :)

This commit is contained in:
Donald Zou 2024-06-18 03:16:42 +08:00
parent 760a4dfcb9
commit 327d66bb80
46 changed files with 1866 additions and 7038 deletions

32
.gitignore vendored
View File

@ -18,3 +18,35 @@ src/db/wgdashboard.db
node_modules/**
*/proxy.js
src/static/app/proxy.js
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo
proxy.js
.vite/*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,938 +0,0 @@
body {
font-size: .875rem;
/*font-family: 'Poppins', sans-serif;*/
}
.codeFont{
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
.feather {
width: 16px;
height: 16px;
vertical-align: text-bottom;
}
.btn-primary {
font-weight: bold;
}
.dashboardLogo{
background: -webkit-linear-gradient(#178bff, #ff4a00);
}
/*
* Sidebar
*/
/*.sidebar {*/
/* position: fixed;*/
/* top: 0;*/
/* bottom: 0;*/
/* left: 0;*/
/* z-index: 100;*/
/* !* Behind the navbar *!*/
/* padding: 48px 0 0;*/
/* !* Height of navbar *!*/
/* box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);*/
/*}*/
/*.sidebar-sticky {*/
/* position: relative;*/
/* top: 0;*/
/* height: calc(100vh - 48px);*/
/* padding-top: .5rem;*/
/* overflow-x: hidden;*/
/* overflow-y: auto;*/
/* !* Scrollable contents if viewport is shorter than content. *!*/
/*}*/
/*@supports ((position: -webkit-sticky) or (position: sticky)) {*/
/* .sidebar-sticky {*/
/* position: -webkit-sticky;*/
/* position: sticky;*/
/* }*/
/*}*/
.sidebar .nav-link, .bottomNavContainer .nav-link{
font-weight: 500;
color: #333;
transition: 0.2s cubic-bezier(0.82, -0.07, 0, 1.01);
}
.nav-link:hover {
padding-left: 30px;
background-color: #dfdfdf;
}
.sidebar .nav-link .feather {
margin-right: 4px;
color: #999;
}
.sidebar .nav-link.active, .bottomNavContainer .nav-link.active {
color: #007bff;
}
.sidebar .nav-link:hover .feather,
.sidebar .nav-link.active .feather {
color: inherit;
}
.sidebar-heading {
font-size: .75rem;
text-transform: uppercase;
}
/*
* Navbar
*/
.navbar-brand {
padding-top: .75rem;
padding-bottom: .75rem;
font-size: 1rem;
/*background-color: rgba(0, 0, 0, .25);*/
/*box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);*/
}
.navbar .navbar-toggler {
top: .25rem;
right: 1rem;
}
.form-control {
transition: all 0.2s ease-in-out;
}
.form-control:disabled {
cursor: not-allowed;
}
.navbar .form-control {
padding: .75rem 1rem;
border-width: 0;
border-radius: 0;
}
.form-control-dark {
color: #fff;
background-color: rgba(255, 255, 255, .1);
border-color: rgba(255, 255, 255, .1);
}
.form-control-dark:focus {
border-color: transparent;
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
}
.dot {
width: 10px;
height: 10px;
border-radius: 50px;
display: inline-block;
margin-left: auto !important;
}
.dot-running {
background-color: #28a745!important;
box-shadow: 0 0 0 0.2rem #28a74545;
}
.h6-dot-running {
margin-left: 0.3rem;
}
.dot-stopped {
background-color: #6c757d!important;
}
.card-running {
border-color: #28a745;
}
.info h6 {
line-break: anywhere;
transition: all 0.4s cubic-bezier(0.96, -0.07, 0.34, 1.01);
opacity: 1;
}
.info .row .col-sm {
display: flex;
flex-direction: column;
}
.info .row .col-sm small {
display: flex;
}
.info .row .col-sm small strong:last-child(1) {
margin-left: auto !important;
}
.btn-control {
border: none !important;
padding: 0;
margin: 0 1rem 0 0;
}
.btn-control:hover{
background-color: transparent !important;
}
.btn-control:active,
.btn-control:focus {
background-color: transparent !important;
border: none !important;
box-shadow: none;
}
.btn-qrcode-peer {
padding: 0 !important;
}
.btn-qrcode-peer:active,
.btn-qrcode-peer:hover {
transform: scale(0.9) rotate(180deg);
border: 0 !important;
}
.btn-download-peer:active,
.btn-download-peer:hover {
color: #17a2b8 !important;
transform: translateY(5px);
}
.share_peer_btn_group .btn-control {
margin: 0 0 0 1rem;
padding: 0 !important;
transition: all 0.4s cubic-bezier(1, -0.43, 0, 1.37);
}
.btn-control:hover {
background: white;
}
.btn-delete-peer:hover {
color: #dc3545;
}
.btn-lock-peer:hover {
color: #28a745;
}
.btn-lock-peer.lock{
color: #6c757d
}
.btn-lock-peer.lock:hover{
color: #6c757d
}
.btn-control.btn-outline-primary:hover{
color: #007bff
}
/* .btn-setting-peer:hover {
color: #007bff
} */
.btn-download-peer:hover {
color: #17a2b8;
}
.login-container {
padding: 2rem;
}
@media (max-width: 992px) {
.card-col {
margin-bottom: 1rem;
}
}
.switch {
font-size: 2rem;
}
.switch:hover {
text-decoration: none
}
.btn-group-label:hover {
color: #007bff;
border-color: #007bff;
background: white;
}
.peer_data_group {
text-align: right;
display: flex;
margin-bottom: 0.5rem
}
.peer_data_group p {
text-transform: uppercase;
margin-bottom: 0;
margin-right: 1rem
}
@media (max-width: 768px) {
.peer_data_group {
text-align: left;
}
}
.index-switch {
display: flex;
align-items: center;
justify-content: flex-end;
}
main {
margin-bottom: 3rem;
}
.peer_list {
margin-bottom: 7rem
}
@media (max-width: 768px) {
.add_btn {
bottom: 1.5rem !important;
}
.peer_list {
margin-bottom: 7rem !important;
}
}
.btn-manage-group {
z-index: 99;
position: fixed;
bottom: 3rem;
right: 2rem;
display: flex;
}
.btn-manage-group .setting_btn_menu {
position: absolute;
top: -124px;
background-color: white;
padding: 1rem 0;
right: 0;
box-shadow: 0 10px 20px rgb(0 0 0 / 19%), 0 6px 6px rgb(0 0 0 / 23%);
border-radius: 10px;
min-width: 250px;
display: none;
transform: translateY(-30px);
opacity: 0;
transition: all 0.3s cubic-bezier(0.58, 0.03, 0.05, 1.28);
}
.btn-manage-group .setting_btn_menu.show {
display: block;
}
.setting_btn_menu.showing {
transform: translateY(0px);
opacity: 1;
}
.setting_btn_menu a {
display: flex;
padding: 0.5rem 1rem;
transition: all 0.1s ease-in-out;
font-size: 1rem;
align-items: center;
cursor: pointer;
}
.setting_btn_menu a:hover {
background-color: #efefef;
text-decoration: none;
}
.setting_btn_menu a i {
margin-right: auto !important;
}
.add_btn {
height: 54px;
z-index: 99;
border-radius: 100px !important;
padding: 0 14px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
margin-right: 1rem;
font-size: 1.5rem;
}
.setting_btn {
height: 54px;
z-index: 99;
border-radius: 100px !important;
padding: 0 14px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
font-size: 1.5rem;
}
@-webkit-keyframes rotating
/* Safari and Chrome */
{
from {
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes rotating {
from {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.rotating::before {
-webkit-animation: rotating 0.75s linear infinite;
-moz-animation: rotating 0.75s linear infinite;
-ms-animation: rotating 0.75s linear infinite;
-o-animation: rotating 0.75s linear infinite;
animation: rotating 0.75s linear infinite;
}
.peer_private_key_textbox_switch {
position: absolute;
right: 2rem;
transform: translateY(-28px);
font-size: 1.2rem;
cursor: pointer;
}
#peer_private_key_textbox,
#private_key,
#public_key,
#peer_preshared_key_textbox {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
.progress-bar {
transition: 0.3s ease-in-out;
}
.key {
transition: 0.2s ease-in-out;
cursor: pointer;
}
.key:hover {
color: #007bff;
}
.card {
border-radius: 10px;
}
.peer_list .card .button-group {
height: 22px;
}
.form-control {
border-radius: 10px;
}
.btn {
border-radius: 8px;
/*padding: 0.6rem 0.9em;*/
}
.login-box #username,
.login-box #password {
padding: 0.6rem calc( 0.9rem + 32px);
height: inherit;
}
.login-box label[for="username"],
.login-box label[for="password"] {
font-size: 1rem;
margin: 0 !important;
transform: translateY(2.1rem) translateX(1rem);
padding: 0;
}
/*label[for="password"]{*/
/* transform: translateY(32px) translateX(16px);*/
/*}*/
.modal-content {
border-radius: 10px;
}
.tooltip-inner {
font-size: 0.8rem;
}
@-webkit-keyframes loading {
0% {
background-color: #dfdfdf;
}
50% {
background-color: #adadad;
}
100% {
background-color: #dfdfdf;
}
}
@-moz-keyframes loading {
0% {
background-color: #dfdfdf;
}
50% {
background-color: #adadad;
}
100% {
background-color: #dfdfdf;
}
}
.conf_card {
transition: 0.2s ease-in-out;
}
.conf_card:hover {
border-color: #007bff;
cursor: pointer;
}
.info_loading {
/* animation: loading 2s infinite ease-in-out;
/* border-radius: 5px; */
height: 19.19px;
/* transition: 0.3s ease-in-out; */
/* transform: translateX(40px); */
opacity: 0 !important;
}
#conf_status_btn {
transition: 0.2s ease-in-out;
}
#conf_status_btn.info_loading {
height: 38px;
border-radius: 5px;
animation: loading 3s infinite ease-in-out;
}
#qrcode_img img {
width: 100%;
}
#selected_ip_list .badge,
#selected_peer_list .badge {
margin: 0.1rem
}
#add_modal.ip_modal_open {
transition: filter 0.2s ease-in-out;
filter: brightness(0.5);
}
#delete_bulk_modal .list-group a.active {
background-color: #dc3545;
border-color: #dc3545;
}
#selected_peer_list {
max-height: 80px;
overflow-y: scroll;
overflow-x: hidden;
}
.no-response {
width: 100%;
height: 100%;
position: fixed;
background: #000000ba;
z-index: 10000;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
opacity: 0;
transition: all 1s ease-in-out;
}
.no-response.active {
display: flex;
}
.no-response.active.show {
opacity: 100;
}
.no-response .container>* {
text-align: center;
}
.no-responding {
transition: all 1s ease-in-out;
filter: blur(10px);
}
pre.index-alert {
margin-bottom: 0;
padding: 1rem;
background-color: #343a40;
border: 1px solid rgba(0, 0, 0, .125);
border-radius: .25rem;
margin-top: 1rem;
color: white;
}
.peerNameCol {
display: flex;
align-items: center;
margin-bottom: 0.2rem
}
.peerName {
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.peerLightContainer {
text-transform: uppercase;
margin: 0;
margin-left: auto !important;
}
.conf_card .dot,
.info .dot {
transform: translateX(10px);
}
#config_body {
transition: 0.3s ease-in-out;
}
#config_body.firstLoading {
opacity: 0.2;
}
.chartTitle {
display: flex;
}
.chartControl {
margin-bottom: 1rem;
display: flex;
align-items: center;
}
.chartTitle h6 {
margin-bottom: 0;
line-height: 1;
margin-right: 0.5rem;
}
.chartContainer.fullScreen {
position: fixed;
z-index: 9999;
background-color: white;
top: 0;
left: 0;
width: calc( 100% + 15px);
height: 100%;
padding: 32px;
}
.chartContainer.fullScreen .col-sm {
padding-right: 0;
height: 100%;
}
.chartContainer.fullScreen .chartCanvasContainer {
width: 100%;
height: calc( 100% - 47px) !important;
max-height: calc( 100% - 47px) !important;
}
#switch{
transition: all 200ms ease-in;
}
.toggle--switch{
display: none;
}
.toggleLabel{
width: 64px;
height: 32px;
background-color: #6c757d17;
display: flex;
position: relative;
border: 2px solid #6c757d8c;
border-radius: 100px;
transition: all 200ms ease-in;
cursor: pointer;
margin: 0;
}
.toggle--switch.waiting + .toggleLabel{
opacity: 0.5;
}
.toggleLabel::before{
background-color: #6c757d;
height: 26px;
width: 26px;
content: "";
border-radius: 100px;
margin: 1px;
position: absolute;
animation-name: off;
animation-duration: 350ms;
animation-fill-mode: forwards;
transition: all 200ms ease-in;
cursor: pointer;
}
.toggleLabel:hover::before{
filter: brightness(1.2);
}
.toggle--switch:checked + .toggleLabel{
background-color: #007bff17 !important;
border: 2px solid #007bff8c;
}
.toggle--switch:checked + .toggleLabel::before{
background-color: #007bff;
animation-name: on;
animation-duration: 350ms;
animation-fill-mode: forwards;
}
@keyframes on {
0%{
left: 0px;
}
60%{
left: 0px;
width: 40px;
}
100%{
left: 32px;
width: 26px;
}
}
@keyframes off {
0%{
left: 32px;
}
60%{
left: 18px;
width: 40px;
}
100%{
left: 0px;
width: 26px;
}
}
.toastContainer{
z-index: 99999 !important;
}
.toast{
min-width: 300px;
background-color: rgba(255,255,255,1);
z-index: 99999;
}
.toast-header{
background-color: rgba(255,255,255);
}
.toast-progressbar{
width: 100%;
height: 4px;
background-color: #007bff;
border-bottom-left-radius: .25rem;
}
.addConfigurationAvailableIPs{
margin-bottom: 0;
}
.input-feedback{
display: none;
}
#addConfigurationModal label{
display: flex;
width: 100%;
align-items: center;
}
#addConfigurationModal label a{
margin-left: auto !important;
}
#reGeneratePrivateKey{
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
}
.addConfigurationToggleStatus.waiting{
opacity: 0.5;
}
/*.conf_card .card-body .row .card-col{*/
/* margin-bottom: 0.5rem;*/
/*}*/
.peerDataUsageChartContainer{
min-height: 50vh;
width: 100%;
}
.peerDataUsageChartControl{
display: block !important;
margin: 0;
}
.peerDataUsageChartControl .switchUnit{
width: 33.3%;
}
.peerDataUsageChartControl .switchTimePeriod{
width: 25%;
}
@media (min-width: 1200px){
#peerDataUsage .modal-xl {
max-width: 95vw;
}
}
.bottom{
display: none;
}
@media (max-width: 768px){
.bottom{
display: block;
}
.btn-manage-group{
bottom: calc( 3rem + 40px + env(safe-area-inset-bottom, 5px));
}
main{
padding-bottom: calc( 3rem + 40px + env(safe-area-inset-bottom, 5px));
}
}
.bottomNavContainer{
display: flex;
color: #333;
padding-bottom: env(safe-area-inset-bottom, 5px);
box-shadow: inset 0 1px 0 rgb(0 0 0 / 10%);
}
.bottomNavButton{
width: 25vw;
display: flex;
flex-direction: column;
align-items: center;
margin: 0.7rem 0;
color: rgba(51, 51, 51, 0.5);
cursor: pointer;
transition: all ease-in 0.2s;
}
.bottomNavButton.active{
color: #333;
}
.bottomNavButton i{
font-size: 1.2rem;
}
.bottomNavButton .subNav{
width: 100vw;
position: absolute;
z-index: 10000;
bottom: 0;
left: 0;
background-color: #272b30;
display: none;
animation-duration: 400ms;
padding-bottom: env(safe-area-inset-bottom, 5px);
}
.bottomNavButton .subNav.active{
display: block;
}
.bottomNavButton .subNav .nav .nav-item .nav-link{
padding: 0.7rem 1rem;
}
.bottomNavWrapper{
height: 100%;
width: 100%;
background-color: #000000a1;
position: fixed;
z-index: 1030;
display: none;
left: 0;
}
.bottomNavWrapper.active{
display: block;
}
.sb-update-url .dot-running{
transform: translateX(10px);
}
.list-group-item{
transition: all 0.1s ease-in;
}
.theme-switch-btn{
width: 100%;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/static/app/dist/favicon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

View File

@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/static/app/dist/favicon.ico">
<link rel="icon" href="/static/app/dist/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<title>WGDashboard</title>
<script type="module" crossorigin src="/static/app/dist/assets/index.js"></script>
<link rel="stylesheet" crossorigin href="/static/app/dist/assets/index.css">
</head>

View File

@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<link rel="icon" href="/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<title>WGDashboard</title>
</head>
<body>
<div id="app" class="w-100 vh-100"></div>

View File

@ -23,19 +23,19 @@
"qrcode": "^1.5.3",
"qrcodejs": "^1.0.0",
"uuid": "^9.0.1",
"vue": "^3.3.11",
"vue": "^3.4.29",
"vue-chartjs": "^5.3.0",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.2",
"@vitejs/plugin-vue": "^5.0.0",
"vite": "^5.0.10"
}
},
"node_modules/@babel/parser": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
"integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
"bin": {
"parser": "bin/babel-parser.js"
},
@ -613,62 +613,62 @@
"integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz",
"integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==",
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz",
"integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==",
"dev": true,
"engines": {
"node": "^14.18.0 || >=16.0.0"
"node": "^18.0.0 || >=20.0.0"
},
"peerDependencies": {
"vite": "^4.0.0 || ^5.0.0",
"vite": "^5.0.0",
"vue": "^3.2.25"
}
},
"node_modules/@vue/compiler-core": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.3.tgz",
"integrity": "sha512-u8jzgFg0EDtSrb/hG53Wwh1bAOQFtc1ZCegBpA/glyvTlgHl+tq13o1zvRfLbegYUw/E4mSTGOiCnAJ9SJ+lsg==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.29.tgz",
"integrity": "sha512-TFKiRkKKsRCKvg/jTSSKK7mYLJEQdUiUfykbG49rubC9SfDyvT2JrzTReopWlz2MxqeLyxh9UZhvxEIBgAhtrg==",
"dependencies": {
"@babel/parser": "^7.23.6",
"@vue/shared": "3.4.3",
"@babel/parser": "^7.24.7",
"@vue/shared": "3.4.29",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.3.tgz",
"integrity": "sha512-oGF1E9/htI6JWj/lTJgr6UgxNCtNHbM6xKVreBWeZL9QhRGABRVoWGAzxmtBfSOd+w0Zi5BY0Es/tlJrN6WgEg==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.29.tgz",
"integrity": "sha512-A6+iZ2fKIEGnfPJejdB7b1FlJzgiD+Y/sxxKwJWg1EbJu6ZPgzaPQQ51ESGNv0CP6jm6Z7/pO6Ia8Ze6IKrX7w==",
"dependencies": {
"@vue/compiler-core": "3.4.3",
"@vue/shared": "3.4.3"
"@vue/compiler-core": "3.4.29",
"@vue/shared": "3.4.29"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.3.tgz",
"integrity": "sha512-NuJqb5is9I4uzv316VRUDYgIlPZCG8D+ARt5P4t5UDShIHKL25J3TGZAUryY/Aiy0DsY7srJnZL5ryB6DD63Zw==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.29.tgz",
"integrity": "sha512-zygDcEtn8ZimDlrEQyLUovoWgKQic6aEQqRXce2WXBvSeHbEbcAsXyCk9oG33ZkyWH4sl9D3tkYc1idoOkdqZQ==",
"dependencies": {
"@babel/parser": "^7.23.6",
"@vue/compiler-core": "3.4.3",
"@vue/compiler-dom": "3.4.3",
"@vue/compiler-ssr": "3.4.3",
"@vue/shared": "3.4.3",
"@babel/parser": "^7.24.7",
"@vue/compiler-core": "3.4.29",
"@vue/compiler-dom": "3.4.29",
"@vue/compiler-ssr": "3.4.29",
"@vue/shared": "3.4.29",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.5",
"postcss": "^8.4.32",
"source-map-js": "^1.0.2"
"magic-string": "^0.30.10",
"postcss": "^8.4.38",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.3.tgz",
"integrity": "sha512-wnYQtMBkeFSxgSSQbYGQeXPhQacQiog2c6AlvMldQH6DB+gSXK/0F6DVXAJfEiuBSgBhUc8dwrrG5JQcqwalsA==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.29.tgz",
"integrity": "sha512-rFbwCmxJ16tDp3N8XCx5xSQzjhidYjXllvEcqX/lopkoznlNPz3jyy0WGJCyhAaVQK677WWFt3YO/WUEkMMUFQ==",
"dependencies": {
"@vue/compiler-dom": "3.4.3",
"@vue/shared": "3.4.3"
"@vue/compiler-dom": "3.4.29",
"@vue/shared": "3.4.29"
}
},
"node_modules/@vue/devtools-api": {
@ -677,48 +677,49 @@
"integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA=="
},
"node_modules/@vue/reactivity": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.3.tgz",
"integrity": "sha512-q5f9HLDU+5aBKizXHAx0w4whkIANs1Muiq9R5YXm0HtorSlflqv9u/ohaMxuuhHWCji4xqpQ1eL04WvmAmGnFg==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.29.tgz",
"integrity": "sha512-w8+KV+mb1a8ornnGQitnMdLfE0kXmteaxLdccm2XwdFxXst4q/Z7SEboCV5SqJNpZbKFeaRBBJBhW24aJyGINg==",
"dependencies": {
"@vue/shared": "3.4.3"
"@vue/shared": "3.4.29"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.3.tgz",
"integrity": "sha512-C1r6QhB1qY7D591RCSFhMULyzL9CuyrGc+3PpB0h7dU4Qqw6GNyo4BNFjHZVvsWncrUlKX3DIKg0Y7rNNr06NQ==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.29.tgz",
"integrity": "sha512-s8fmX3YVR/Rk5ig0ic0NuzTNjK2M7iLuVSZyMmCzN/+Mjuqqif1JasCtEtmtoJWF32pAtUjyuT2ljNKNLeOmnQ==",
"dependencies": {
"@vue/reactivity": "3.4.3",
"@vue/shared": "3.4.3"
"@vue/reactivity": "3.4.29",
"@vue/shared": "3.4.29"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.3.tgz",
"integrity": "sha512-wrsprg7An5Ec+EhPngWdPuzkp0BEUxAKaQtN9dPU/iZctPyD9aaXmVtehPJerdQxQale6gEnhpnfywNw3zOv2A==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.29.tgz",
"integrity": "sha512-gI10atCrtOLf/2MPPMM+dpz3NGulo9ZZR9d1dWo4fYvm+xkfvRrw1ZmJ7mkWtiJVXSsdmPbcK1p5dZzOCKDN0g==",
"dependencies": {
"@vue/runtime-core": "3.4.3",
"@vue/shared": "3.4.3",
"@vue/reactivity": "3.4.29",
"@vue/runtime-core": "3.4.29",
"@vue/shared": "3.4.29",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.3.tgz",
"integrity": "sha512-BUxt8oVGMKKsqSkM1uU3d3Houyfy4WAc2SpSQRebNd+XJGATVkW/rO129jkyL+kpB/2VRKzE63zwf5RtJ3XuZw==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.29.tgz",
"integrity": "sha512-HMLCmPI2j/k8PVkSBysrA2RxcxC5DgBiCdj7n7H2QtR8bQQPqKAe8qoaxLcInzouBmzwJ+J0x20ygN/B5mYBng==",
"dependencies": {
"@vue/compiler-ssr": "3.4.3",
"@vue/shared": "3.4.3"
"@vue/compiler-ssr": "3.4.29",
"@vue/shared": "3.4.29"
},
"peerDependencies": {
"vue": "3.4.3"
"vue": "3.4.29"
}
},
"node_modules/@vue/shared": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.3.tgz",
"integrity": "sha512-rIwlkkP1n4uKrRzivAKPZIEkHiuwY5mmhMJ2nZKCBLz8lTUlE73rQh4n1OnnMurXt1vcUNyH4ZPfdh8QweTjpQ=="
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.29.tgz",
"integrity": "sha512-hQ2gAQcBO/CDpC82DCrinJNgOHI2v+FA7BDW4lMSPeBpQ7sRe2OLHWe5cph1s7D8DUQAwRt18dBDfJJ220APEA=="
},
"node_modules/@vueuse/core": {
"version": "10.9.0",
@ -1118,14 +1119,11 @@
}
},
"node_modules/magic-string": {
"version": "0.30.5",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
"integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
"version": "0.30.10",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
"integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
"engines": {
"node": ">=12"
}
},
"node_modules/nanoid": {
@ -4000,15 +3998,15 @@
}
},
"node_modules/vue": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.3.tgz",
"integrity": "sha512-GjN+culMAGv/mUbkIv8zMKItno8npcj5gWlXkSxf1SPTQf8eJ4A+YfHIvQFyL1IfuJcMl3soA7SmN1fRxbf/wA==",
"version": "3.4.29",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.29.tgz",
"integrity": "sha512-8QUYfRcYzNlYuzKPfge1UWC6nF9ym0lx7mpGVPJYNhddxEf3DD0+kU07NTL0sXuiT2HuJuKr/iEO8WvXvT0RSQ==",
"dependencies": {
"@vue/compiler-dom": "3.4.3",
"@vue/compiler-sfc": "3.4.3",
"@vue/runtime-dom": "3.4.3",
"@vue/server-renderer": "3.4.3",
"@vue/shared": "3.4.3"
"@vue/compiler-dom": "3.4.29",
"@vue/compiler-sfc": "3.4.29",
"@vue/runtime-dom": "3.4.29",
"@vue/server-renderer": "3.4.29",
"@vue/shared": "3.4.29"
},
"peerDependencies": {
"typescript": "*"

View File

@ -24,12 +24,12 @@
"qrcode": "^1.5.3",
"qrcodejs": "^1.0.0",
"uuid": "^9.0.1",
"vue": "^3.3.11",
"vue": "^3.4.29",
"vue-chartjs": "^5.3.0",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.2",
"@vitejs/plugin-vue": "^5.0.0",
"vite": "^5.0.10"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

View File

@ -86,6 +86,7 @@ export default {
<PeerSettingsDropdown
@qrcode="(file) => this.$emit('qrcode', file)"
@setting="this.$emit('setting')"
@jobs="this.$emit('jobs')"
@refresh="this.$emit('refresh')"
:Peer="Peer"
v-if="this.subMenuOpened"

View File

@ -1,54 +1,100 @@
<script>
import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJobsComponents/scheduleDropdown.vue";
import SchedulePeerJob from "@/components/configurationComponents/peerScheduleJobsComponents/schedulePeerJob.vue";
export default {
name: "peerJobs"
name: "peerJobs",
props:{
selectedPeer: Object
},
components:{
SchedulePeerJob,
ScheduleDropdown,
},
data(){
return {
dropdowns: {
Field: [
{
display: "Total Received",
value: "total_receive"
},
{
display: "Total Sent",
value: "total_sent"
},
{
display: "Total Data",
value: "total_data"
},
{
display: "Date",
value: "date"
}
],
Operator: [
{
display: "equal",
value: "eq"
},
{
display: "not equal",
value: "neq"
},
{
display: "larger than",
value: "lgt"
},
{
display: "less than",
value: "lst"
},
],
Action: [
{
display: "Restrict Peer",
value: "restrict"
},
{
display: "Delete Peer",
value: "delete"
}
]
},
}
},
}
</script>
<template>
<div class="container po">
<div class="mb-5">
<RouterLink to="peers" is="div" class="d-flex align-items-center gap-4 text-decoration-none">
<h3 class="mb-0 text-body">
<i class="bi bi-chevron-left"></i>
</h3>
<h3 class="text-body mb-0">Peer Jobs</h3>
</RouterLink>
</div>
<div>
<div class="row">
<div class="col-sm-4">
<small class="text-muted">Peer</small>
<p class="mb-0"><samp>ymoO2hZDAxnMXOcMML7rnE5ot8lLoh9Uma8mzt1TwAc=</samp></p>
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0">
<div class="container d-flex h-100 w-100">
<div class="card m-auto rounded-3 shadow" style="width: 700px">
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2">
<h4 class="mb-0 fw-normal">Schedule Jobs
<strong></strong>
</h4>
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
</div>
<div class="col-sm-8">
<div class="card shadow-sm rounded-3">
<div class="card-header bg-transparent text-muted border-0">
<small class="d-flex">
<strong class="me-auto">Job ID</strong>
7e9b5ef2-9417-4399-88a4-79ac378edfae
</small>
</div>
<div class="card-body pt-1">
<div class="d-flex gap-3 align-items-center">
<samp>
if
</samp>
<div class="dropdown">
<button class="btn btn-sm btn-outline-primary rounded-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<samp>Total Received</samp>
</button>
<ul class="dropdown-menu rounded-3">
<li><a class="dropdown-item" href="#">Total Usage</a></li>
<li><a class="dropdown-item" href="#">Total Sent</a></li>
<li><a class="dropdown-item" href="#">Total Received</a></li>
</ul>
</div>
<samp>
is
</samp>
</div>
</div>
<div class="card-body px-4 pb-4 pt-0">
<div class="d-flex">
<small class="text-muted">
Name
</small>
<small class="ms-auto">{{selectedPeer.name ? selectedPeer.name : "Untitled Peer"}}</small>
</div>
<div class="mb-4 d-flex">
<small class="text-muted">
Public Key
</small>
<small class="ms-auto"><samp>{{this.selectedPeer.id}}</samp></small>
</div>
<SchedulePeerJob
:dropdowns="this.dropdowns"
:job="job" v-for="job in this.selectedPeer.jobs">
</SchedulePeerJob>
</div>
</div>
</div>

View File

@ -36,6 +36,7 @@ import dayjs from "dayjs";
import PeerSettings from "@/components/configurationComponents/peerSettings.vue";
import PeerQRCode from "@/components/configurationComponents/peerQRCode.vue";
import PeerCreate from "@/components/configurationComponents/peerCreate.vue";
import PeerJobs from "@/components/configurationComponents/peerJobs.vue";
Chart.register(
ArcElement,
@ -65,7 +66,7 @@ Chart.register(
export default {
name: "peerList",
components: {PeerCreate, PeerQRCode, PeerSettings, PeerSearch, Peer, Line, Bar},
components: {PeerJobs, PeerCreate, PeerQRCode, PeerSettings, PeerSearch, Peer, Line, Bar},
setup(){
const dashboardConfigurationStore = DashboardConfigurationStore();
const wireguardConfigurationStore = WireguardConfigurationsStore();
@ -108,6 +109,10 @@ export default {
modalOpen: false,
selectedPeer: undefined
},
peerScheduleJobs:{
modalOpen: false,
selectedPeer: undefined
},
peerQRCode: {
modalOpen: false,
peerConfigData: undefined
@ -523,6 +528,7 @@ export default {
v-for="peer in this.searchPeers">
<Peer :Peer="peer"
@refresh="this.getPeers()"
@jobs="peerScheduleJobs.modalOpen = true; peerScheduleJobs.selectedPeer = this.configurationPeers.find(x => x.id === peer.id)"
@setting="peerSetting.modalOpen = true; peerSetting.selectedPeer = this.configurationPeers.find(x => x.id === peer.id)"
@qrcode="(file) => {this.peerQRCode.peerConfigData = file; this.peerQRCode.modalOpen = true;}"
></Peer>
@ -530,18 +536,33 @@ export default {
</TransitionGroup>
</div>
<Transition name="fade">
<PeerSettings v-if="this.peerSetting.modalOpen"
<PeerSettings v-if="this.peerSetting.modalOpen"
key="settings"
:selectedPeer="this.peerSetting.selectedPeer"
@refresh="this.getPeers()"
@close="this.peerSetting.modalOpen = false">
</PeerSettings>
</Transition>
<Transition name="fade">
<PeerQRCode :peerConfigData="this.peerQRCode.peerConfigData"
<PeerQRCode :peerConfigData="this.peerQRCode.peerConfigData"
key="qrcode"
@close="this.peerQRCode.modalOpen = false"
v-if="peerQRCode.modalOpen"></PeerQRCode>
</Transition>
<Transition name="fade">
<PeerJobs
v-if="this.peerScheduleJobs.modalOpen"
:selectedPeer="this.peerScheduleJobs.selectedPeer"
@close="this.peerScheduleJobs.modalOpen = false">
</PeerJobs>
</Transition>
<!-- <Transition name="fade">-->
<!-- -->
<!-- </Transition>-->
<!-- <Transition name="fade">-->
<!-- -->
<!-- </Transition>-->
</div>
</template>

View File

@ -0,0 +1,39 @@
<script>
export default {
name: "scheduleDropdown",
props: {
options: Array,
data: String,
},
mounted() {
console.log(this.options)
},
computed:{
currentSelection(){
return this.options.find(x => x.value === this.data)
}
}
}
</script>
<template>
<div class="dropdown">
<button class="btn btn-sm btn-outline-primary rounded-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<samp>{{this.currentSelection.display}}</samp>
</button>
<ul class="dropdown-menu rounded-3 shadow" style="font-size: 0.875rem; width: 200px">
<li v-for="x in this.options">
<a class="dropdown-item d-flex align-items-center" role="button" @click="$emit('update', x.value)">
<samp>{{x.display}}</samp>
<i class="bi bi-check ms-auto" v-if="x.value === this.currentSelection.value"></i>
</a>
</li>
</ul>
</div>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,67 @@
<script>
import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJobsComponents/scheduleDropdown.vue";
export default {
name: "schedulePeerJob",
components: {ScheduleDropdown},
props: {
dropdowns: Array[Object],
job: Object
}
}
</script>
<template>
<div class="card shadow-sm rounded-3">
<div class="card-header bg-transparent text-muted border-0">
<small class="d-flex">
<strong class="me-auto">Job ID</strong>
{{this.job.JobID}}
</small>
</div>
<div class="card-body pt-1">
<div class="d-flex gap-3 align-items-center mb-2">
<samp>
if
</samp>
<ScheduleDropdown
:options="this.dropdowns.Field"
:data="this.job.Field"
@update="(value) => this.job.Field = value"
></ScheduleDropdown>
<samp>
is
</samp>
<ScheduleDropdown
:options="this.dropdowns.Operator"
:data="this.job.Operator"
@update="(value) => this.job.Operator = value"
></ScheduleDropdown>
<input class="form-control form-control-sm form-control-dark rounded-3 flex-grow-1" style="width: auto">
<samp>
{
</samp>
</div>
<div class="px-5 d-flex gap-3 align-items-center">
<samp>
execute
</samp>
<ScheduleDropdown
:options="this.dropdowns.Action"
:data="this.job.Action"
@update="(value) => this.job.Action = value"
></ScheduleDropdown>
<samp>
;
</samp>
</div>
<div>
<samp>}</samp>
</div>
</div>
</div>
</template>
<style scoped>
</style>

View File

@ -76,11 +76,11 @@ export default {
<i class="bi bi-plus-lg me-2"></i>Peers
</RouterLink>
<RouterLink
to="jobs"
class="text-decoration-none btn btn-primary rounded-3 btn-sm">
<i class="bi bi-app-indicator me-2"></i>Jobs
</RouterLink>
<!-- <RouterLink-->
<!-- to="jobs"-->
<!-- class="text-decoration-none btn btn-primary rounded-3 btn-sm">-->
<!-- <i class="bi bi-app-indicator me-2"></i>Jobs-->
<!-- </RouterLink>-->
<button class="btn btn-sm btn-primary rounded-3" @click="this.downloadAllPeer()">
<i class="bi bi-download me-2"></i> Download All
</button>

View File

@ -175,10 +175,6 @@ export default {
>
Save Peer<i class="bi bi-save-fill ms-2"></i></button>
</div>
</div>
</div>
</div>
@ -187,10 +183,6 @@ export default {
</template>
<style scoped>
.peerSettingContainer {
background-color: #00000060;
z-index: 1000;
}
.toggleShowKey{
position: absolute;
top: 35px;

View File

@ -102,6 +102,13 @@ export default {
<i class="me-auto bi bi-pen"></i> Edit
</a>
</li>
<li>
<a class="dropdown-item d-flex" role="button"
@click="this.$emit('jobs')"
>
<i class="me-auto bi bi-app-indicator"></i> Schedule Jobs
</a>
</li>
<template v-if="this.Peer.private_key">
<li>
<a class="dropdown-item d-flex" role="button" @click="this.downloadPeer()">

View File

@ -90,11 +90,7 @@ const router = createRouter({
path: 'create',
component: PeerCreate
},
{
name: "Peer Jobs",
path: 'jobs',
component: PeerJobs
},
]
},

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1114,4 +1114,9 @@ pre.index-alert {
animations can be calculated correctly. */
.list-leave-active {
position: absolute;
}
.peerSettingContainer {
background-color: #00000060;
z-index: 9999;
}

File diff suppressed because one or more lines are too long

View File

@ -1,391 +0,0 @@
:root {
--green: hsl(120deg, 30%, 50%) !important;
--blue: hsl(235deg, 60%, 60%) !important;
--red: hsl(0deg, 60%, 60%) !important;
--magenta: hsl(315deg, 60%, 60%) !important;
}
body {
background: #222222;
color: hsl(0deg, 0%, 80%);
}
a.text-primary:focus, a.text-primary:hover {
color: hsl(235deg, 60%, 50%) !important;
}
.btn-primary {
color: hsl(0deg, 0%, 90%) !important;
border-color: hsl(235deg, 60%, 60%) !important;
background: hsl(235deg, 60%, 60%) !important;
}
.btn-primary:hover {
background-color: hsl(235deg, 60%, 50%) !important;
border-color: hsl(235deg, 60%, 50%) !important;
}
.btn-outline-primary {
color: hsl(235deg, 60%, 60%) !important;
border-color: hsl(235deg, 60%, 60%) !important;
background: transparent !important;
}
.btn-outline-primary:hover, .btn-outline-primary.active {
color: hsl(0deg, 0%, 90%) !important;
}
.btn-outline-primary.active {
background-color: hsl(235deg, 60%, 60%) !important;
border-color: hsl(235deg, 60%, 60%) !important;
}
.btn-outline-primary:hover {
background-color: hsl(235deg, 60%, 50%) !important;
border-color: hsl(235deg, 60%, 50%) !important;
}
.btn-success {
color: hsl(0deg, 0%, 90%) !important;
border-color: hsl(120deg, 30%, 50%) !important;
background: hsl(120deg, 30%, 50%) !important;
}
.btn-success:hover {
background-color: hsl(120deg, 30%, 40%) !important;
border-color: hsl(120deg, 30%, 40%) !important;
}
.list-group-item {
background-color: #272727;
border-color: #272727;
color: white;
}
.list-group-item:hover {
background-color: #333333;
border-color: #333333;
color: white;
}
.delete-peer-bulk-badge.badge-danger {
background-color: hsl(0deg, 60%, 60%);
}
.delete-peer-bulk-badge.badge-danger:hover {
background-color: hsl(0deg, 60%, 50%);
}
#delete_bulk_modal .list-group a.active {
background-color: hsl(0deg, 60%, 60%);
border: hsl(0deg, 60%, 60%);
}
#delete_bulk_modal .list-group a.active:hover {
background-color: hsl(0deg, 60%, 50%);
border: hsl(0deg, 60%, 50%);
}
#available_ip_modal .list-group a.active {
background-color: hsl(235deg, 60%, 60%);
border: hsl(235deg, 60%, 60%);
}
#available_ip_modal .list-group a.active:hover {
background-color: hsl(235deg, 60%, 50%);
border: hsl(235deg, 60%, 50%);
}
.available-ip-badge.badge-primary {
background-color: hsl(235deg, 60%, 60%);
}
.available-ip-badge.badge-primary:hover {
background-color: hsl(235deg, 60%, 50%);
}
.btn-outline-success {
color: hsl(120deg, 30%, 50%) !important;
border-color: hsl(120deg, 30%, 50%) !important;
background: transparent !important;
}
.btn-outline-success:hover, .btn-outline-success.active {
color: hsl(0deg, 0%, 90%) !important;
}
.btn-outline-success.active {
background-color: hsl(120deg, 30%, 50%) !important;
border-color: hsl(120deg, 30%, 50%) !important;
}
.btn-outline-success:hover {
background-color: hsl(120deg, 30%, 40%) !important;
border-color: hsl(120deg, 30%, 40%) !important;
}
.btn-danger {
color: hsl(0deg, 0%, 90%) !important;
border-color: hsl(0deg, 60%, 60%) !important;
background: hsl(0deg, 60%, 60%) !important;
}
.btn-danger:hover {
background-color: hsl(0deg, 60%, 50%) !important;
border-color: hsl(0deg, 60%, 50%) !important;
}
.btn-outline-danger {
color: hsl(0deg, 60%, 60%) !important;
border-color: hsl(0deg, 60%, 60%) !important;
background: transparent !important;
}
.btn-outline-danger:hover, .btn-outline-danger.active {
color: hsl(0deg, 0%, 90%) !important;
}
.btn-outline-danger.active {
background-color: hsl(0deg, 60%, 60%) !important;
border-color: hsl(0deg, 60%, 60%) !important;
}
.btn-outline-danger:hover {
background-color: hsl(0deg, 60%, 50%) !important;
border-color: hsl(0deg, 60%, 50%) !important;
}
.btn-secondary {
color: hsl(0deg, 0%, 90%) !important;
border-color: #424242 !important;
background: #424242 !important;
}
.btn-secondary:hover {
background-color: #383838 !important;
border-color: #383838 !important;
}
.btn-outline-secondary {
color: #424242 !important;
border-color: #424242 !important;
background: transparent !important;
}
.btn-outline-secondary:hover, .btn-outline-secondary.active {
color: hsl(0deg, 0%, 90%) !important;
}
.btn-outline-secondary.active {
background-color: #424242 !important;
border-color: #424242 !important;
}
.btn-outline-secondary:hover {
background-color: #383838 !important;
border-color: #383838 !important;
}
.btn-control.btn-lock-peer.lock {
color: hsl(0deg, 60%, 60%) !important;
}
.btn-control.btn-lock-peer.lock:hover {
color: hsl(0deg, 60%, 50%) !important;
}
.btn-control:hover {
background-color: transparent !important;
}
.btn-control:hover.btn-outline-primary {
color: hsl(235deg, 60%, 50%) !important;
}
.btn-control:hover.btn-outline-success {
color: hsl(120deg, 30%, 40%) !important;
}
.btn-control:hover.btn-outline-danger {
color: hsl(0deg, 60%, 50%) !important;
}
.btn-control:hover.btn-outline-secondary {
color: #383838 !important;
}
.form-control {
background-color: #2c2c2c !important;
border-color: transparent !important;
color: hsl(0deg, 0%, 80%) !important;
}
.form-control:disabled {
color: #777777 !important;
}
.card .form-control {
background: #2c2c2c !important;
}
.conf_card a {
color: hsl(235deg, 60%, 60%);
}
.conf_card:hover {
border-color: hsl(235deg, 60%, 60%);
}
.sidebar .nav-link,
.bottomNavContainer .nav-link {
color: hsl(0deg, 0%, 80%);
}
.sidebar .nav-link:hover,
.bottomNavContainer .nav-link:hover {
background: #222222;
}
nav#sidebarMenu.col-md-3.col-lg-2.d-md-block.bg-light.sidebar.collapse,
.navbar-brand,
.bg-dark {
background-color: #1e1e1e !important;
background: #1e1e1e !important;
}
.card {
background: #272727;
}
.text-muted {
color: hsl(0deg, 0%, 50%) !important;
}
.text-danger {
color: hsl(0deg, 60%, 60%) !important;
}
.text-success {
color: hsl(120deg, 30%, 50%) !important;
}
.text-primary {
color: hsl(235deg, 60%, 60%) !important;
}
.text-info {
color: hsl(190deg, 60%, 60%) !important;
}
a.text-success:focus,
a.text-success:hover {
color: hsl(120deg, 30%, 40%) !important;
}
a.text-danger:focus,
a.text-danger:hover {
color: hsl(0deg, 60%, 50%) !important;
}
a.text-info:focus,
a.text-info:hover {
color: hsl(190deg, 60%, 50%) !important;
}
.dot-running {
background-color: hsl(120deg, 30%, 50%) !important;
}
.card-running {
border-color: hsl(120deg, 30%, 50%);
}
.toggle--switch:checked + .toggleLabel::before {
background-color: hsl(235deg, 60%, 60%) !important;
}
.toggle--switch:checked + .toggleLabel {
background-color: #2e336b !important;
border-color: hsl(235deg, 60%, 60%) !important;
}
.sidebar .nav-link.active,
.bottomNavContainer .nav-link.active {
color: hsl(235deg, 60%, 60%) !important;
}
hr {
border-color: #2e2e2e;
}
.modal-content {
background-color: #222222;
}
.modal-header,
.modal-footer {
background-color: #1e1e1e;
border-color: #2e2e2e;
}
code {
color: hsl(315deg, 60%, 60%);
}
.close {
color: hsl(0deg, 0%, 80%);
text-shadow: none;
}
.close:hover {
color: hsl(0deg, 0%, 70%);
}
.chartContainer.fullScreen {
background-color: #222222 !important;
}
.popover {
background-color: #333333 !important;
border: none !important;
}
.popover-body {
color: hsl(0deg, 0%, 80%) !important;
}
div.toast {
background-color: #424242 !important;
}
div.toast div.toast-header {
background-color: #333333 !important;
color: hsl(0deg, 0%, 80%) !important;
border-bottom-color: #424242 !important;
}
div.toast div.toast-body {
background-color: #383838 !important;
color: hsl(0deg, 0%, 80%) !important;
}
div.toast div.toast-body.text-danger {
color: hsl(0deg, 60%, 60%) !important;
}
div.toast div.toast-progressbar {
background-color: hsl(235deg, 60%, 60%) !important;
}
div.toast div.toast-progressbar.bg-danger {
background-color: hsl(0deg, 60%, 60%) !important;
}
.bs-popover-auto[x-placement^=right] > .arrow::after,
.bs-popover-right > .arrow::after {
border-right-color: #333333 !important;
}
.btn-manage-group .setting_btn_menu {
background-color: #2c2c2c !important;
}
.setting_btn_menu a:hover {
background-color: #333333 !important;
}
.table {
color: hsl(0deg, 0%, 80%) !important;
}
.table th,
.table td {
border-color: #333333 !important;
}
.btn-outline-primary.focus, .btn-outline-primary:focus, .btn-primary.focus, .btn-primary:focus {
box-shadow: 0 0 0 0.2rem rgba(144, 153, 255, 0.29) !important;
}
.bottomNav {
background-color: #272727 !important;
}
.bottomNav .bottomNavButton {
color: hsl(0deg, 0%, 60%);
}
.bottomNav .bottomNavButton.active {
color: hsl(235deg, 60%, 60%) !important;
}
.bottomNav .subNav {
background-color: #272727 !important;
}
.key:hover {
color: hsl(235deg, 60%, 60%);
}
/*# sourceMappingURL=dark.css.map */

View File

@ -1 +0,0 @@
{"version":3,"sourceRoot":"","sources":["dark.scss"],"names":[],"mappings":"AAgCA;EACE;EACA;EACA;EACA;;;AAGF;EACE,YAvCS;EAwCT,OAdS;;;AAiBX;EACE;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE,kBAzFS;EA0FT,cA1FS;EA2FT;;AAEA;EACE,kBA3FO;EA4FP,cA5FO;EA6FP;;;AAMJ;EACE,kBA3FQ;;AA4FR;EACE,kBA9FM;;;AAoGN;EACE,kBApGI;EAqGJ,QArGI;;AAuGJ;EACE,kBAzGE;EA0GF,QA1GE;;;AAkHN;EACE,kBA/GK;EAgHL,QAhHK;;AAkHL;EACE,kBApHG;EAqHH,QArHG;;;AA2HX;EACE,kBA3HS;;AA4HT;EACE,kBA9HO;;;AAkIX;EACE;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAKF;EACE;;AACA;EACE;;AAIJ;EACE;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAKN;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIA;EACE,OAnQO;;AAqQT;EACE,cAtQO;;;AA0QX;AAAA;EAEE,OAnQS;;AAqQT;AAAA;EACE,YAhSO;;;AAoSX;AAAA;AAAA;EAGE;EACA;;;AAGF;EACE,YA1SS;;;AA6SX;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE,cA5UU;;;AA+UZ;EACE;;;AAEF;EACE;EACA;;;AAGF;AAAA;EAEE;;;AAGF;EACE,cApWS;;;AAuWX;EACE,kBA5WS;;;AA+WX;AAAA;EAEE,kBAlXS;EAmXT,cA9WS;;;AAiXX;EACE,OA/VY;;;AAkWd;EACE,OAhWS;EAiWT;;AAEA;EACE,OAnWO;;;AAuWX;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;AAEA;AAAA;EAEE;;;AAKJ;EACE;;;AAIA;EACE;;AAIA;EACE,OAhbK;;AAobT;EACE;;AAGF;EACE;;;AAKJ;EACE,OA1cS","file":"dark.css"}

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
{"version":3,"sourceRoot":"","sources":["dark.scss"],"names":[],"mappings":"AAgCA,MACE,0CACA,yCACA,sCACA,4CAGF,KACE,WAvCS,KAwCT,MAdS,KAiBX,0CACE,yBAGF,aACE,yBACA,gCACA,8BAEA,mBACE,oCACA,gCAIJ,qBACE,yBACA,gCACA,oCAEA,uDAEE,yBAGF,4BACE,oCACA,gCAGF,2BACE,oCACA,gCAIJ,aACE,yBACA,gCACA,8BAEA,mBACE,oCACA,gCAIJ,iBACE,iBAzFS,QA0FT,aA1FS,QA2FT,WAEA,uBACE,iBA3FO,KA4FP,aA5FO,KA6FP,WAMJ,qCACE,iBA3FQ,QA4FR,2CACE,iBA9FM,KAoGN,wCACE,iBApGI,QAqGJ,OArGI,QAuGJ,8CACE,iBAzGE,KA0GF,OA1GE,KAkHN,yCACE,iBA/GK,QAgHL,OAhHK,QAkHL,+CACE,iBApHG,QAqHH,OArHG,QA2HX,kCACE,iBA3HS,QA4HT,wCACE,iBA9HO,QAkIX,qBACE,yBACA,gCACA,oCAEA,uDAEE,yBAGF,4BACE,oCACA,gCAGF,2BACE,oCACA,gCAIJ,YACE,yBACA,gCACA,8BAEA,kBACE,iCACA,6BAIJ,oBACE,yBACA,gCACA,oCAEA,qDAEE,yBAGF,2BACE,oCACA,gCAGF,0BACE,iCACA,6BAIJ,eACE,yBACA,gCACA,8BAEA,qBACE,oCACA,gCAIJ,uBACE,yBACA,gCACA,oCAEA,2DAEE,yBAGF,8BACE,oCACA,gCAGF,6BACE,oCACA,gCAKF,gCACE,yBACA,sCACE,sBAIJ,mBACE,0CAEA,uCACE,yBAGF,uCACE,yBAGF,sCACE,sBAGF,yCACE,yBAKN,cACE,oCACA,sCACA,sBAGF,uBACE,sBAGF,oBACE,8BAIA,aACE,MAnQO,QAqQT,iBACE,aAtQO,QA0QX,iDAEE,MAnQS,KAqQT,6DACE,WAhSO,KAoSX,8FAGE,oCACA,8BAGF,MACE,WA1SS,QA6SX,YACE,sBAGF,aACE,yBAGF,cACE,yBAGF,cACE,yBAGF,WACE,yBAGF,0CAEE,yBAGF,wCAEE,sBAGF,oCAEE,yBAGF,aACE,oCAGF,cACE,aA5UU,QA+UZ,6CACE,oCAEF,qCACE,oCACA,gCAGF,+DAEE,yBAGF,GACE,aApWS,QAuWX,eACE,iBA5WS,KA+WX,4BAEE,iBAlXS,QAmXT,aA9WS,QAiXX,KACE,MA/VY,QAkWd,OACE,MAhWS,KAiWT,iBAEA,aACE,MAnWO,QAuWX,2BACE,iCAGF,SACE,iCACA,uBAGF,cACE,sBAGF,UACE,oCAEA,2BACE,iCACA,sBACA,uCAGF,yBACE,oCACA,sBAGF,qCACE,yBAGF,gCACE,oCAGF,0CACE,oCAIJ,mFAEE,mCAGF,oCACE,oCAGF,0BACE,iCAGF,OACE,sBAEA,oBAEE,6BAKJ,4FACE,wDAIA,WACE,oCAIA,4BACE,MAhbK,KAobT,mCACE,yBAGF,mBACE,oCAKJ,WACE,MA1cS","file":"dark.min.css"}

File diff suppressed because one or more lines are too long

View File

@ -1,480 +0,0 @@
$grey-100: #1e1e1e;
$grey-200: #222222;
$grey-300: #242424;
$grey-400: #272727;
$grey-500: #2c2c2c;
$grey-600: #2e2e2e;
$grey-700: #333333;
$grey-800: #383838;
$grey-900: #424242;
$grey-1000: #777777;
$green-400: hsl(120deg, 30%, 40%);
$green-500: hsl(120deg, 30%, 50%);
$red-400: hsl(0deg, 60%, 50%);
$red-500: hsl(0deg, 60%, 60%);
$blue-400: hsl(235deg, 60%, 50%);
$blue-500: hsl(235deg, 60%, 60%);
$blue-400-clear: rgba(51, 64, 204, 0.25);
$cyan-400: hsl(190deg, 60%, 50%);
$cyan-500: hsl(190deg, 60%, 60%);
$magenta-500: hsl(315deg, 60%, 60%);
$text-100: hsl(0deg, 0%, 90%);
$text-200: hsl(0deg, 0%, 80%);
$text-300: hsl(0deg, 0%, 70%);
$text-400: hsl(0deg, 0%, 60%);
$text-500: hsl(0deg, 0%, 50%);
:root {
--green: #{$green-500} !important;
--blue: #{$blue-500} !important;
--red: #{$red-500} !important;
--magenta: #{$magenta-500} !important;
}
body {
background: $grey-200;
color: $text-200;
}
a.text-primary:focus, a.text-primary:hover{
color: $blue-400 !important;
}
.btn-primary {
color: $text-100 !important;
border-color: $blue-500 !important;
background: $blue-500 !important;
&:hover {
background-color: $blue-400 !important;
border-color: $blue-400 !important;
}
}
.btn-outline-primary {
color: $blue-500 !important;
border-color: $blue-500 !important;
background: transparent !important;
&:hover,
&.active {
color: $text-100 !important;
}
&.active {
background-color: $blue-500 !important;
border-color: $blue-500 !important;
}
&:hover {
background-color: $blue-400 !important;
border-color: $blue-400 !important;
}
}
.btn-success {
color: $text-100 !important;
border-color: $green-500 !important;
background: $green-500 !important;
&:hover {
background-color: $green-400 !important;
border-color: $green-400 !important;
}
}
.list-group-item{
background-color: $grey-400;
border-color: $grey-400;
color: white;
&:hover{
background-color: $grey-700;
border-color: $grey-700;
color: white;
}
}
.delete-peer-bulk-badge.badge-danger{
background-color: $red-500;
&:hover{
background-color: $red-400;
}
}
#delete_bulk_modal{
.list-group{
a.active{
background-color: $red-500;
border: $red-500;
&:hover{
background-color: $red-400;
border: $red-400;
}
}
}
}
#available_ip_modal{
.list-group{
a.active{
background-color: $blue-500;
border: $blue-500;
&:hover{
background-color: $blue-400;
border: $blue-400;
}
}
}
}
.available-ip-badge.badge-primary{
background-color: $blue-500;
&:hover{
background-color: $blue-400;
}
}
.btn-outline-success {
color: $green-500 !important;
border-color: $green-500 !important;
background: transparent !important;
&:hover,
&.active {
color: $text-100 !important;
}
&.active {
background-color: $green-500 !important;
border-color: $green-500 !important;
}
&:hover {
background-color: $green-400 !important;
border-color: $green-400 !important;
}
}
.btn-danger {
color: $text-100 !important;
border-color: $red-500 !important;
background: $red-500 !important;
&:hover {
background-color: $red-400 !important;
border-color: $red-400 !important;
}
}
.btn-outline-danger {
color: $red-500 !important;
border-color: $red-500 !important;
background: transparent !important;
&:hover,
&.active {
color: $text-100 !important;
}
&.active {
background-color: $red-500 !important;
border-color: $red-500 !important;
}
&:hover {
background-color: $red-400 !important;
border-color: $red-400 !important;
}
}
.btn-secondary {
color: $text-100 !important;
border-color: $grey-900 !important;
background: $grey-900 !important;
&:hover {
background-color: $grey-800 !important;
border-color: $grey-800 !important;
}
}
.btn-outline-secondary {
color: $grey-900 !important;
border-color: $grey-900 !important;
background: transparent !important;
&:hover,
&.active {
color: $text-100 !important;
}
&.active {
background-color: $grey-900 !important;
border-color: $grey-900 !important;
}
&:hover {
background-color: $grey-800 !important;
border-color: $grey-800 !important;
}
}
.btn-control {
&.btn-lock-peer.lock {
color: $red-500 !important;
&:hover {
color: $red-400 !important;
}
}
&:hover {
background-color: transparent !important;
&.btn-outline-primary {
color: $blue-400 !important;
}
&.btn-outline-success {
color: $green-400 !important;
}
&.btn-outline-danger {
color: $red-400 !important;
}
&.btn-outline-secondary {
color: $grey-800 !important;
}
}
}
.form-control {
background-color: $grey-500 !important;
border-color: transparent !important;
color: $text-200 !important;
}
.form-control:disabled{
color: $grey-1000 !important;
}
.card .form-control {
background: $grey-500 !important;
}
.conf_card{
a{
color: $blue-500;
}
&:hover{
border-color: $blue-500;
}
}
.sidebar .nav-link,
.bottomNavContainer .nav-link {
color: $text-200;
&:hover {
background: $grey-200;
}
}
nav#sidebarMenu.col-md-3.col-lg-2.d-md-block.bg-light.sidebar.collapse,
.navbar-brand,
.bg-dark {
background-color: $grey-100 !important;
background: $grey-100 !important;
}
.card {
background: $grey-400;
}
.text-muted {
color: $text-500 !important;
}
.text-danger {
color: $red-500 !important;
}
.text-success {
color: $green-500 !important;
}
.text-primary {
color: $blue-500 !important;
}
.text-info {
color: $cyan-500 !important;
}
a.text-success:focus,
a.text-success:hover {
color: $green-400 !important;
}
a.text-danger:focus,
a.text-danger:hover {
color: $red-400 !important;
}
a.text-info:focus,
a.text-info:hover {
color: $cyan-400 !important;
}
.dot-running {
background-color: $green-500 !important;
}
.card-running {
border-color: $green-500;
}
.toggle--switch:checked + .toggleLabel::before {
background-color: $blue-500 !important;
}
.toggle--switch:checked + .toggleLabel {
background-color: mix($blue-500, #000f) !important;
border-color: $blue-500 !important;
}
.sidebar .nav-link.active,
.bottomNavContainer .nav-link.active {
color: $blue-500 !important;
}
hr {
border-color: $grey-600;
}
.modal-content {
background-color: $grey-200;
}
.modal-header,
.modal-footer {
background-color: $grey-100;
border-color: $grey-600;
}
code {
color: $magenta-500;
}
.close {
color: $text-200;
text-shadow: none;
&:hover {
color: $text-300;
}
}
.chartContainer.fullScreen {
background-color: $grey-200 !important;
}
.popover {
background-color: $grey-700 !important;
border: none !important;
}
.popover-body {
color: $text-200 !important;
}
div.toast {
background-color: $grey-900 !important;
div.toast-header {
background-color: $grey-700 !important;
color: $text-200 !important;
border-bottom-color: $grey-900 !important;
}
div.toast-body {
background-color: $grey-800 !important;
color: $text-200 !important;
}
div.toast-body.text-danger{
color: $red-500 !important;
}
div.toast-progressbar {
background-color: $blue-500 !important;
}
div.toast-progressbar.bg-danger {
background-color: $red-500 !important;
}
}
.bs-popover-auto[x-placement^="right"] > .arrow::after,
.bs-popover-right > .arrow::after {
border-right-color: $grey-700 !important;
}
.btn-manage-group .setting_btn_menu {
background-color: $grey-500 !important;
}
.setting_btn_menu a:hover {
background-color: $grey-700 !important;
}
.table {
color: $text-200 !important;
th,
td {
border-color: $grey-700 !important;
}
}
.btn-outline-primary.focus, .btn-outline-primary:focus, .btn-primary.focus, .btn-primary:focus{
box-shadow: 0 0 0 0.2rem rgb(144 153 255 / 29%) !important;
}
.bottomNav{
&{
background-color: $grey-400 !important;
}
.bottomNavButton{
&{
color: $text-400;
}
}
.bottomNavButton.active{
color: $blue-500 !important;
}
.subNav{
background-color: $grey-400 !important;
}
}
.key:hover{
color: $blue-500;
}

View File

@ -1,201 +0,0 @@
<!-- configuration.html - < WGDashboard > - Copyright(C) 2021 Donald Zou [https://github.com/donaldzou]-->
<html lang="en">
{% with title=title%}
{% include "header.html"%}
{% endwith %}
<body>
<div class="no-response">
<div class="container">
<h1 class="text-white display-1"><i class="bi bi-emoji-frown-fill"></i></h1>
<h4 class="text-white">Oops!<br>I can't connect to the server.</h4>
</div>
</div>
{% include "navbar.html" %}
<div class="container-fluid" id="right_body">
{% include "sidebar.html" %}
<div id="config_body">
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mt-4 mb-4">
<div class="info mt-4">
<div>
<pre class="index-alert d-none" style="margin-bottom: 1rem;"></pre>
</div>
<div class="row">
<div class="col">
<small class="text-muted"><strong>CONFIGURATION</strong></small>
<h1 class="mb-3"><samp id="conf_name">{{ title }}</samp></h1>
</div>
<div class="col">
<small class="text-muted"><strong>TOGGLE</strong></small><br>
<!-- <div id="conf_status_btn" class="info_loading"></div> -->
<div id="switch" class="info_loading">
<input type="checkbox" class="toggle--switch" id="toggle--switch">
<label for="toggle--switch" class="toggleLabel"></label>
</div>
</div>
<div class="w-100"></div>
<div class="col">
<small class="text-muted"><strong>STATUS</strong></small>
<h6 style="text-transform: uppercase;" id="conf_status" class="info_loading"></h6>
</div>
<div class="col">
<small class="text-muted"><strong>CONNECTED PEERS</strong></small>
<h6 style="text-transform: uppercase;" id="conf_connected_peers" class="info_loading"></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL DATA USAGE</strong></small>
<h6 style="text-transform: uppercase;" id="conf_total_data_usage" class="info_loading"></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL RECEIVED</strong></small>
<h6 style="text-transform: uppercase;" id="conf_total_data_received" class="info_loading">
</h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL SENT</strong></small>
<h6 style="text-transform: uppercase;" id="conf_total_data_sent" class="info_loading"></h6>
</div>
<div class="w-100"></div>
<div class="col-sm">
<small class="text-muted">
<strong>PUBLIC KEY</strong>
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out"
class="text-primary">CLICK TO COPY</strong>
</small>
<h6 class="info_loading"><samp class="key" id="conf_public_key"></samp></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>LISTEN PORT</strong></small>
<h6 style="text-transform: uppercase;" class="info_loading"><samp
id="conf_listen_port"></samp></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>ADDRESS</strong></small>
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_address"></samp>
</h6>
</div>
</div>
</div>
<hr>
<div class="row chartContainer">
<div class="col-sm">
<div class="chartTitle">
<h6>Data Usage / Refresh Interval</h6>
<div class="chartControl" style="margin-left: auto">
<div class="btn-group" role="group">
<button class="btn btn-outline-primary btn-sm switchUnit" data-unit="GB">GB</button>
<button class="btn btn-outline-primary btn-sm switchUnit" data-unit="MB">MB</button>
<button class="btn btn-outline-primary btn-sm switchUnit" data-unit="KB">KB</button>
<button class="btn btn-outline-primary btn-sm fullScreen"><i
class="bi bi-fullscreen"></i></button>
</div>
</div>
</div>
<div class="chartCanvasContainer" style="width: 100%; height: 300px">
<canvas id="totalDataUsageChartObj" width="100" height="100"></canvas>
</div>
</div>
</div>
<hr>
<div class="button-div mb-3">
<div class="row">
<div class="col-md">
<div class="row">
<div class="col-md">
<div class="form-group">
<label for="search_peer_textbox"><small class="text-muted">Search
Peers</small></label>
<input type="text" class="form-control" id="search_peer_textbox"
placeholder="Enter Peer's Name" value="">
</div>
</div>
<div class="col-md">
<div class="form-group">
<label for="sort_by_dropdown"><small class="text-muted">Sort Peers
By</small></label>
<select class="form-control" id="sort_by_dropdown">
<option value="status">Status</option>
<option value="name">Name</option>
<option value="allowed_ip">Allowed IP</option>
</select>
</div>
</div>
</div>
</div>
<div class="col-md">
<div class="form-group">
<label><small class="text-muted">Refresh Interval</small></label><br>
<div class="btn-group interval-btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button"
class="btn btn-outline-primary btn-group-label refresh" data-toggle="tooltip"
data-placement="bottom" title="Refresh Peers"><i
class="bi bi-arrow-repeat"></i></button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="5000">5s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="10000">10s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="30000">30s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="60000">1m</button>
</div>
</div>
</div>
<div class="col-md">
<div class="form-group">
<label><small class="text-muted">Display Mode</small></label><br>
<div class="btn-group display-btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button"
class="btn btn-outline-primary display_mode" data-display-mode="grid"><i
class="bi bi-grid-fill" style="font-size: 1.5rem;"></i></button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary display_mode" data-display-mode="list"><i
class="bi bi-list" style="font-size: 1.5rem;"></i></button>
</div>
</div>
</div>
<div class="btn-manage-group">
<button type="button" class="btn btn-primary add_btn"><i
class="bi bi-plus-circle-fill"></i></button>
<button type="button" class="btn btn-secondary setting_btn"><i
class="bi bi-three-dots"></i></button>
<div class="setting_btn_menu">
<a class="text-danger" id="delete_peers_by_bulk_btn"><i class="bi bi-trash-fill"></i>
Delete Peers</a>
<a class="text-info" id="download_all_peers"
data-url="/download_all/{{conf_data['name']}}"><i
class="bi bi-cloud-download-fill"></i> Download All Peers</a>
<hr>
<a class="text-primary" id="edit_configuration"><i class="bi bi-gear-fill"></i>
Configration Settings</a>
<a class="text-danger" id="configuration_delete"><i class="bi bi-trash3-fill"></i>
Delete Configuration</a>
</div>
</div>
</div>
</div>
<div class="row peer_list"></div>
<small id="peer_loading_time" class="text-muted"></small>
</main>
</div>
</div>
{% include "modal.html" %}
<div class="position-fixed top-0 right-0 p-3 toastContainer" style="z-index: 5; right: 0; top: 50px;"></div>
{% include "tools.html" %}
</body>
{% include "footer.html" %}
<script src="{{ url_for('static',filename='js/configuration.js') }}"></script>
<script src="{{ url_for('static',filename='js/configurationTool.js') }}"></script>
<script src="{{ url_for('static',filename='js/wireguard.js') }}"></script>
<script>
configurations.setConfigurationName("{{ conf_data['name'] }}");
configurations.setActiveConfigurationName();
configurations.loadPeers($('#search_peer_textbox').val());
</script>
</html>

View File

@ -1,3 +0,0 @@
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script><script src="{{ url_for('static',filename='js/tools.js') }}"></script>
<script src="{{ url_for('static',filename='js/pwa.js') }}"></script>

View File

@ -1,184 +0,0 @@
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mt-4 mb-4">
<div class="info mt-4">
{% if conf_data['listen_port'] == "" and conf_data['status'] == "stopped" %}
<div class="alert alert-warning" role="alert">Peer QR Code and configuration file download required a specified <strong>Listen Port</strong>.</div>
{% endif %}
{% if conf_data['conf_address'] == "N/A" %}
<div class="alert alert-warning" role="alert">
Configuration <strong>Address</strong> not be specified to have peer connect to it.
</div>
{% endif %}
<div class="row">
<div class="col">
<small class="text-muted"><strong>CONFIGURATION</strong></small>
<h1 class="mb-3"><samp>{{conf_data['name']}}</samp></h1>
</div>
<div class="col">
<small class="text-muted"><strong>ACTION</strong></small><br>
{% if conf_data['checked'] == "checked" %}
<a href="#" id="{{conf_data['name']}}" {{conf_data['checked']}} class="switch text-primary"><i class="bi bi-toggle2-on"></i> ON</a>
{% else %}
<a href="#" id="{{conf_data['name']}}" {{conf_data['checked']}} class="switch text-secondary"><i class="bi bi-toggle2-off"></i> OFF</a>
{% endif %}
<div class="spinner-border text-primary" role="status" style="display: none; margin-top: 10px">
<span class="sr-only">Loading...</span>
</div>
</div>
<div class="w-100"></div>
<div class="col">
<small class="text-muted"><strong>STATUS</strong></small>
<h6 style="text-transform: uppercase;">{{conf_data['status']}}<span class="dot dot-{{conf_data['status']}}"></span></h6>
</div>
<div class="col">
<small class="text-muted"><strong>CONNECTED PEERS</strong></small>
<h6 style="text-transform: uppercase;">{{conf_data['running_peer']}}</h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL DATA USAGE</strong></small>
<h6 style="text-transform: uppercase;">{{conf_data['total_data_usage'][0]}} GB</h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL RECEIVED</strong></small>
<h6 style="text-transform: uppercase;">{{conf_data['total_data_usage'][1]}} GB</h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL SENT</strong></small>
<h6 style="text-transform: uppercase;">{{conf_data['total_data_usage'][2]}} GB</h6>
</div>
<div class="w-100"></div>
<div class="col-sm">
<small class="text-muted">
<strong>PUBLIC KEY</strong>
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong>
</small>
<h6><samp class="key">{{conf_data['public_key']}}</samp></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>LISTEN PORT</strong></small>
<h6 style="text-transform: uppercase;"><samp>
{% if conf_data['listen_port'] == "" %}
N/A
{% else %}
{{conf_data['listen_port']}}
{% endif %}
</samp></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>ADDRESS</strong></small>
<h6 style="text-transform: uppercase;"><samp>{{conf_data['conf_address']}}</samp></h6>
</div>
</div>
<hr>
<div class="button-div mb-3">
<div class="row">
<div class="col-sm">
<div class="form-group">
<label for="sort_by_dropdown"><small class="text-muted">Sort Peers By</small></label>
<select class="form-control" id="sort_by_dropdown">
<option value="status" {% if sort_tag == "status" %} {{ "selected" }} {% endif %}>Status</option>
<option value="name" {% if sort_tag == "name" %} {{ "selected" }} {% endif %}>Name</option>
<option value="allowed_ip" {% if sort_tag == "allowed_ip" %} {{ "selected" }} {% endif %}>Allowed IP</option>
</select>
</div>
</div>
<div class="col-sm">
<div class="form-group">
<label><small class="text-muted">Refresh Interval</small></label><br>
<div class="btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button" class="btn btn-outline-primary btn-group-label refresh"><i class="bi bi-arrow-repeat"></i></button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 5000 %} {{ "active" }} {% endif %}" refresh-interval="5000">5s</button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 10000 %} {{ "active" }} {% endif %}" refresh-interval="10000">10s</button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 30000 %} {{ "active" }} {% endif %}" refresh-interval="30000">30s</button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 60000 %} {{ "active" }} {% endif %}" refresh-interval="60000">1m</button>
</div>
</div>
</div>
<div class="col-sm">
<div class="form-group">
<label><small class="text-muted">Display Mode</small></label><br>
<div class="btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode {% if peer_display_mode == "grid" %} {{ "active" }} {% endif %}" display-mode="grid"><i class="bi bi-grid-fill" style="font-size: 1.5rem;"></i></button>
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode {% if peer_display_mode == "list" %} {{ "active" }} {% endif %}" display-mode="list"><i class="bi bi-list" style="font-size: 1.5rem;"></i></button>
</div>
</div>
</div>
<button type="button" class="btn btn-primary add_btn" data-toggle="modal" data-target="#add_modal">
<i class="bi bi-plus-circle-fill" style=""></i> Add Peer
</button>
</div>
</div>
</div>
<div class="row peer_list">
{% if conf_data['peer_data']|length == 0 %}
<div class="col-12" style="text-align: center; margin-top: 1.5rem"><h3 class="text-muted">Oops! No peers found ‘︿’</h3></div>
{% endif %}
{% for i in conf_data['peer_data']%}
{% if peer_display_mode == "list" %}
<div class="col-12">
{% else %}
<div class="col-sm-6 col-lg-4">
{% endif %}
<div class="card mb-3 card-{{i['status']}}">
<div class="card-body">
<div class="row">
<div class="col-sm">
<h4>
{% if not i['name']%}
{{ "Untitled" }}
{% else %}
{{i['name']}}
{% endif %}
</h4>
</div>
<div class="w-100"></div>
<div class="col-6">
<small class="text-muted"><strong>STATUS</strong></small>
<h6 style="text-transform: uppercase;" class="mb-2 h6-dot-{{i['status']}}"><span class="dot dot-{{i['status']}}" style="margin-left: 0 !important;margin-top: 5px"></span></h6>
</div>
<div class="col-6 peer_data_group" style="text-align: right">
<small class="text-muted"><strong>TRANSFER</strong></small>
<p class="text-primary" style="text-transform: uppercase; margin-bottom: 0;"><small><i class="bi bi-arrow-down-right"></i> {{i['total_receive']}} GB</small></p>
<p class="text-success" style="text-transform: uppercase; margin-bottom: 0"><small><i class="bi bi-arrow-up-right"></i> {{i['total_sent']}} GB</small></p>
</div>
<div class="col-sm">
<small class="text-muted" style="display: flex">
<strong>PEER</strong>
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong></small>
<h6><samp class="ml-auto key">{{i['id']}}</samp></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>ALLOWED IP</strong></small>
<h6 style="text-transform: uppercase;">{{i['allowed_ip']}}</h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>LATEST HANDSHAKE</strong></small>
<h6 style="text-transform: uppercase;">{{i['latest_handshake']}}</h6>
</div>
<div class="w-100"></div>
<div class="col-sm">
<small class="text-muted"><strong>END POINT</strong></small>
<h6 style="text-transform: uppercase;">{{i['endpoint']}}</h6>
</div>
<div class="w-100"></div>
<div class="col-sm"><hr><div class="button-group" style="display:flex"><button type="button" class="btn btn-outline-primary btn-setting-peer btn-control" id="{{i['id']}}" data-toggle="modal"><i class="bi bi-gear-fill"></i></button><button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="{{i['id']}}" data-toggle="modal"><i class="bi bi-x-circle-fill"></i></button>
{% if i['private_key'] %}
<div class="share_peer_btn_group" style="margin-left: auto !important; display: inline">
<button type="button" class="btn btn-outline-success btn-qrcode-peer btn-control" img_src="/qrcode/{{ conf_data['name'] }}?id={{ i['id']|urlencode }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width: 19px;" fill="#28a745"><path d="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zM13 3v8h8V3h-8zm6 6h-4V5h4v4zM13 13h2v2h-2zM15 15h2v2h-2zM13 17h2v2h-2zM17 17h2v2h-2zM19 19h2v2h-2zM15 19h2v2h-2zM17 13h2v2h-2zM19 15h2v2h-2z"/></svg>
</button>
<a href="/download/{{ conf_data['name'] }}?id={{ i['id']|urlencode }}" class="btn btn-outline-info btn-download-peer btn-control">
<i class="bi bi-download"></i>
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{%endfor%}
</div>
</main>

View File

@ -1,19 +0,0 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{{ title }} | WGDashboard</title>
<link rel="manifest" href="{{ url_for('static',filename='json/manifest.json') }}">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="WGDashboard">
<meta name="apple-mobile-web-app-title" content="WGDashboard">
<meta name="msapplication-starturl" content="/">
<link rel="apple-touch-icon" sizes="192x192" href="{{ url_for('static',filename='img/192x192ios.png') }}">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="{{ url_for('static',filename='img/logo.png') }}"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='css/dashboard.css') }}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js" integrity="sha512-QSkVNOCYLtj73J4hbmVoOV6KVZuMluZlioC+trLpewV8qMjsWqlIQvkn1KGX2StWvPMdWGBqim1xlC8krl1EKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
</head>

View File

@ -1,164 +1,21 @@
<!-- index.html - < WGDashboard > - Copyright(C) 2021 Donald Zou [https://github.com/donaldzou]-->
<!DOCTYPE html>
<html lang="en">
{% with %}
{% set title="Home" %}
{% include "header.html"%}
{% endwith %}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>WGDashboard</title>
<link rel="manifest" href="{{ url_for('static',filename='json/manifest.json') }}">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="WGDashboard">
<meta name="apple-mobile-web-app-title" content="WGDashboard">
<meta name="msapplication-starturl" content="/">
<link rel="apple-touch-icon" sizes="192x192" href="{{ url_for('static',filename='img/192x192ios.png') }}">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="{{ url_for('static',filename='img/logo.png') }}"/>
<script src="../static/app/dist/assets/index.js" type="module"></script>
</head>
<body>
{% include "navbar.html" %}
<div class="container-fluid">
{% include "sidebar.html" %}
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mb-4" style="margin-bottom: 10rem !important;">
<div style="display: flex; flex-direction: row; align-items: center;">
<h1 class="pb-4 mt-4">Home</h1>
</div>
<!-- {% if msg != "" %}
<div class="alert alert-danger" role="alert">
Configuration toggle failed. Please check the following error message:
</div>
<pre class="index-alert"><code>{{ msg }}</code></pre>
{% endif %} -->
<div class="index-alert alert alert-danger d-none" role="alert">
Configuration toggle failed. Please check the following error message:
</div>
<pre class="index-alert index-alert-full d-none"><code></code></pre>
{% if conf == [] %}
<p class="text-muted">You don't have any WireGuard configurations yet. Please check the configuration folder or change it in "Settings". By default the folder is "/etc/wireguard".</p>
{% endif %}
{% for i in conf %}
<div class="card mt-3 conf_card" data-conf-id="{{i['conf']}}">
<div class="card-body">
<div class="row">
<div class="col card-col">
<small class="text-muted"><strong>CONFIGURATION</strong></small>
<a href="/configuration/{{i['conf']}}" class="conf_link">
<h6 class="card-title" style="margin:0 !important;"><samp>{{i['conf']}}</samp></h6>
</a>
</div>
<div class="col card-col">
<small class="text-muted"><strong>STATUS</strong></small>
<h6 style="text-transform: uppercase; margin:0 !important;"><span>{{i['status']}}</span><span class="dot dot-{{i['status']}}"></span></h6>
</div>
<div class="col-sm card-col">
<small class="text-muted"><strong>PUBLIC KEY</strong></small>
<h6 style="margin:0 !important;"><samp>{{i['public_key']}}</samp></h6>
</div>
<div class="col-sm index-switch">
<div class="switch-test">
<input type="checkbox" class="toggle--switch" id="{{i['conf']}}-switch" {{i['checked']}} data-conf-id="{{i['conf']}}">
<label for="{{i['conf']}}-switch" class="toggleLabel"></label>
</div>
</div>
</div>
<div class="card-message"></div>
</div>
</div>
{%endfor%}
</main>
</div>
<div class="position-fixed top-0 right-0 p-3 toastContainer" style="z-index: 5; right: 0; top: 50px;"></div>
<div class="btn-manage-group">
<button type="button" class="btn btn-primary add_btn" id="toggleAddConfiguration"><i class="bi bi-plus-circle-fill"></i></button>
</div>
<div class="modal fade" id="addConfigurationModal" data-backdrop="static" data-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Add New Configuration</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="addCconfigurationAlert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
<div class="alert-body"></div>
</div>
<pre id="addCconfigurationAlertMessage" class="index-alert d-none"></pre>
<form id="add_configuration_form">
<div class="form-group">
<div>
<label for="addConfigurationPrivateKey">Private Key <code>*</code></label>
</div>
<div class="input-group">
<input type="text" class="form-control codeFont" id="addConfigurationPrivateKey" name="addConfigurationPrivateKey" required>
<div class="input-group-append">
<button type="button" class="btn btn-danger" id="reGeneratePrivateKey" data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i class="bi bi-arrow-repeat"></i></button>
</div>
<div id="addConfigurationPrivateKeyFeedback" class="input-feedback"></div>
</div>
</div>
<div class="row">
<div class="col-sm">
<div class="form-group">
<label for="addConfigurationName">Configuration Name <code>*</code></label>
<input type="text" class="form-control" id="addConfigurationName" name="addConfigurationName" required>
<div id="addConfigurationNameFeedback" class="input-feedback"></div>
</div>
</div>
<div class="col-sm">
<div class="form-group">
<label for="addConfigurationListenPort">Listen Port <code>*</code></label>
<input type="number" class="form-control codeFont" id="addConfigurationListenPort" name="addConfigurationListenPort" required>
<div id="addConfigurationListenPortFeedback" class="input-feedback"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm">
<div class="form-group">
<label for="addConfigurationAddress">Address <code>*</code>
</label>
<input type="text" class="form-control codeFont" id="addConfigurationAddress" placeholder="Ex: 192.168.0.1/24" name="addConfigurationAddress" required>
<div id="addConfigurationAddressFeedback" class="input-feedback"></div>
</div>
</div>
<div class="col-sm">
<div class="form-group">
<label for=""># of available IPs</label>
<p class="addConfigurationAvailableIPs">N/A</p>
</div>
</div>
</div>
<hr>
<div class="form-group">
<label for="addConfigurationPreUp">PreUp</label>
<input type="text" class="form-control codeFont" id="addConfigurationPreUp" name="addConfigurationPreUp">
</div>
<div class="form-group">
<label for="addConfigurationPreDown">PreDown</label>
<input type="text" class="form-control codeFont" id="addConfigurationPreDown" name="addConfigurationPreDown">
</div>
<div class="form-group">
<label for="addConfigurationPostUp">PostUp</label>
<input type="text" class="form-control codeFont" id="addConfigurationPostUp" name="addConfigurationPostUp">
</div>
<div class="form-group">
<label for="addConfigurationPostDown">PostDown</label>
<input type="text" class="form-control codeFont" id="addConfigurationPostDown" name="addConfigurationPostDown">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="addConfigurationBtn">Add</button>
<div class="text-primary addConfigurationStatus addConfigurationAddStatus d-none">
<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>
Add Configuration
</div>
<div class="text-primary addConfigurationStatus addConfigurationToggleStatus d-none waiting">
<i class="bi bi-circle"></i> Toggle Configuration
</div>
</div>
</div>
</div>
</div>
{% include "tools.html" %}
<div id="app" class="w-100 vh-100"></div>
</body>
{% include "footer.html" %}
<script src="{{ url_for('static',filename='js/wireguard.js') }}"></script>
<script src="{{ url_for('static',filename='js/index.js') }}"></script>
</html>

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>WGDashboard</title>
<link rel="manifest" href="{{ url_for('static',filename='json/manifest.json') }}">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="WGDashboard">
<meta name="apple-mobile-web-app-title" content="WGDashboard">
<meta name="msapplication-starturl" content="/">
<link rel="apple-touch-icon" sizes="192x192" href="{{ url_for('static',filename='img/192x192ios.png') }}">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="{{ url_for('static',filename='img/logo.png') }}"/>
<script src="../static/app/dist/assets/index.js" type="module"></script>
<link rel="stylesheet" href="../static/app/dist/assets/index.css">
</head>
<body>
<div id="app" class="w-100 vh-100"></div>
</body>
</html>

View File

@ -1,428 +0,0 @@
<div class="modal fade" id="peerDataUsage">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Data Usage</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div class="row">
<div class="chartControl peerDataUsageChartControl col-sm">
<label><small class="text-muted">Data Unit Size</small></label><br>
<div class="btn-group" role="group" style="width: 100%;">
<button class="btn btn-outline-primary btn-sm switchUnit" data-unit="GB">GB</button>
<button class="btn btn-outline-primary btn-sm switchUnit" data-unit="MB">MB</button>
<button class="btn btn-outline-primary btn-sm switchUnit" data-unit="KB">KB</button>
</div>
</div>
<div class="chartControl peerDataUsageChartControl col-sm">
<label><small class="text-muted">Time Period</small></label><br>
<div class="btn-group" role="group" style="width: 100%;">
<button class="btn btn-outline-primary btn-sm switchTimePeriod" data-time="30min">30
min</button>
<button class="btn btn-outline-primary btn-sm switchTimePeriod" data-time="1h">1hr</button>
<button class="btn btn-outline-primary btn-sm switchTimePeriod" data-time="6h">6hrs</button>
<button class="btn btn-outline-primary btn-sm switchTimePeriod"
data-time="24h">24hrs</button>
<button class="btn btn-outline-primary btn-sm switchTimePeriod" data-time="all">All</button>
</div>
</div>
</div>
<hr>
<small class="text-muted peerDataUsageUpdateTime" style="position: absolute; right: 1rem;">2023</small>
<div class="peerDataUsageChartContainer">
<canvas id="peerDataUsageChartObj"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="add_modal">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Add New Peer</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div>
<div class="custom-control custom-switch" style="margin-bottom: 1rem">
<input class="custom-control-input" type="checkbox" id="bulk_add">
<label class="custom-control-label" for="bulk_add"><strong>Add Peers by
bulk</strong></label>
<i class="bi bi-question-circle-fill" style="cursor: pointer" data-container="body"
data-toggle="popover" data-placement="right" data-trigger="click"
data-content="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></i>
</div>
<div class="form-group" style="margin: 0">
<input type="number" class="form-control" id="new_add_amount" min="1" placeholder="Amount"
disabled>
<div id="bulk_amount_validation" class="invalid-feedback"></div>
</div>
</div>
<hr>
<div id="add_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<form id="add_peer_form">
<div class="form-group">
<div>
<label for="private_key">Private Key</label>
</div>
<div class="input-group">
<input type="text" class="form-control non-bulk" id="private_key"
aria-describedby="private_key">
<div class="input-group-append">
<button type="button" class="btn btn-danger non-bulk" id="re_generate_key"
data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i
class="bi bi-arrow-repeat"></i></button>
</div>
</div>
</div>
<div class="form-group">
<label for="public_key">Public Key <code>(Required)</code></label>
<input type="text" class="form-control non-bulk" id="public_key" aria-describedby="public_key"
disabled>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="new_add_name">Name</label>
<input type="text" class="form-control non-bulk" id="new_add_name">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="allowed_ips">Allowed IPs <code>(Required)</code></label>
<div class="input-group">
<input type="text" class="form-control non-bulk" id="allowed_ips">
<div class="input-group-append">
<button type="button" class="btn btn-primary non-bulk" id="search_available_ip"
data-toggle="tooltip" data-placement="top" title="Search Available IPs">
<i class="bi bi-search"></i>
</button>
</div>
</div>
<p style="position: absolute; top: 4px; right: 1rem;" class="text-success"
id="allowed_ips_indicator"></p>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="new_add_DNS">DNS <code>(Required)</code></label>
<input type="text" class="form-control" id="new_add_DNS" value="{{ DNS }}">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip"
value="{{ endpoint_allowed_ip }}">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="new_add_MTU">MTU</label>
<input type="text" class="form-control" id="new_add_MTU" value="{{ mtu }}">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="new_add_keep_alive">Persistent keepalive</label>
<input type="text" class="form-control" id="new_add_keep_alive"
value="{{ keep_alive }}">
</div>
</div>
<div class="col-sm">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="enable_preshare_key"
name="enable_preshare_key" value="enable_psk">
<label class="form-check-label" for="enable_preshare_key">Use Pre-shared Key</label>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="save_peer">Add</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="configuration_delete_modal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Are you sure to delete this configuration?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="remove_configuration_alert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert">
</div>
<p style="margin: 0">This action is not reversible. The configuration will get toggle off, and
delete from database and from the configuration folder.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">No</button>
<button type="button" class="btn btn-danger" id="sure_delete_configuration">Yes</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="delete_modal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Are you sure to delete this peer?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<h6 style="margin: 0">This action is not reversible.</h6>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">No</button>
<button type="button" class="btn btn-danger" id="delete_peer" conf_id={{conf_data['name']}}
peer_id="">Yes</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="setting_modal" peer_id="">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title peer_name"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="setting_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="mb-3">
<label for="peer_private_key_textbox" class="form-label">Private Key
<code>(Required for QR Code and download)</code></label>
<input type="password" class="form-control" id="peer_private_key_textbox"
style="padding-right: 40px">
<a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a>
</div>
<div>
<label for="peer_preshared_key_textbox" class="form-label">Pre-Shared Key</label>
<input type="text" class="form-control" id="peer_preshared_key_textbox">
</div>
<hr>
<div class="row">
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_name_textbox" class="form-label">Name</label>
<input type="text" class="form-control" id="peer_name_textbox" placeholder="">
</div>
</div>
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_allowed_ip_textbox" class="form-label">Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="peer_allowed_ip_textbox">
</div>
</div>
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_DNS_textbox" class="form-label">DNS <code>(Required)</code></label>
<input type="text" class="form-control" id="peer_DNS_textbox">
</div>
</div>
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_endpoint_allowed_ips" class="form-label">Endpoint Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="peer_endpoint_allowed_ips">
</div>
</div>
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_mtu" class="form-label">MTU</label>
<input type="text" class="form-control" id="peer_mtu">
</div>
</div>
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_keep_alive" class="form-label">Persistent Keepalive</label>
<input type="text" class="form-control" id="peer_keep_alive">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="save_peer_setting" conf_id={{conf_data['name']}}
peer_id="">Save</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="available_ip_modal" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Select available IP</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="selected_ip" style="padding: 1rem; border-bottom: 1px solid #dee2e6;">
<small class="text-muted"><strong>SELECTED IP (CLICK TO REMOVE)</strong></small>
<div id="selected_ip_list"></div>
</div>
<div class="modal-body" style="max-height: 400px; overflow-y: scroll;">
<div class="list-group"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="confirm_ip">Confirm</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="delete_bulk_modal" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Select Peers to Delete</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div id="bulk_remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert"
style="margin: 1rem">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="selected_peers" style="padding: 1rem; border-bottom: 1px solid #dee2e6;">
<small class="text-muted"><strong>SELECTED PEERS (CLICK TO REMOVE)</strong></small>
<div id="selected_peer_list"></div>
</div>
<div class="modal-body" style="max-height: 400px; overflow-y: scroll;">
<div class="list-group"></div>
</div>
<div class="modal-footer">
<a class="text-danger" id="select_all_delete_bulk_peers"
style="cursor: pointer; margin-right: auto;"><small><strong>SELECT ALL</strong></small></a>
<button type="button" class="btn btn-danger" id="confirm_delete_bulk_peers" disabled
data-conf="{{conf_data['name']}}">Delete</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="qrcode_modal" data-backdrop="static" data-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">QR Code</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<img id="qrcode_img" style="width: 100%">
</div>
</div>
</div>
</div>
<div class="modal fade" id="editConfigurationModal">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Edit Configuration</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="addCconfigurationAlert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert">
<div class="alert-body"></div>
</div>
<pre id="addCconfigurationAlertMessage" class="index-alert d-none"></pre>
<form id="add_configuration_form">
<div class="row">
<div class="col-sm">
<div class="form-group">
<label for="editConfigurationName">Configuration Name</label>
<p id="editConfigurationName"></p>
</div>
</div>
<div class="col-sm">
<div class="form-group">
<label for="editConfigurationAddress">Address</label>
<p class="codeFont" id="editConfigurationAddress"></p>
</div>
</div>
</div>
<div class="form-group">
<label for="editConfigurationPrivateKey">Private Key</label>
<p class="codeFont" id="editConfigurationPrivateKey"></p>
</div>
<hr>
<div class="form-group">
<label for="editConfigurationListenPort">Listen Port <code>*</code></label>
<input type="number" class="form-control codeFont" id="editConfigurationListenPort"
name="editConfigurationListenPort" required>
<div id="editConfigurationListenPortFeedback" class="input-feedback"></div>
</div>
<div class="form-group">
<label for="editConfigurationPreUp">PreUp</label>
<input type="text" class="form-control codeFont" id="editConfigurationPreUp"
name="editConfigurationPreUp">
</div>
<div class="form-group">
<label for="editConfigurationPreDown">PreDown</label>
<input type="text" class="form-control codeFont" id="editConfigurationPreDown"
name="editConfigurationPreDown">
</div>
<div class="form-group">
<label for="editConfigurationPostUp">PostUp</label>
<input type="text" class="form-control codeFont" id="editConfigurationPostUp"
name="editConfigurationPostUp">
</div>
<div class="form-group">
<label for="editConfigurationPostDown">PostDown</label>
<input type="text" class="form-control codeFont" id="editConfigurationPostDown"
name="editConfigurationPostDown">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="editConfigurationBtn">Save</button>
</div>
</div>
</div>
</div>

View File

@ -1,12 +0,0 @@
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
<a class="navbar-brand col-md-3 col-lg-2 mr-0 px-3" href="/">WGDashboard</a>
<!-- <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-toggle="collapse"
data-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button> -->
</nav>
<div class="progress" style="height: 3px; position: fixed; width: 100%; z-index: 10000; background-color: transparent">
<div class="progress-bar" role="progressbar" style="z-index: 10000; width: 0%"></div>
</div>

View File

@ -1 +0,0 @@
{{ qrcode(i) }}

View File

@ -1,190 +0,0 @@
<html>
{% with %}
{% set title="Settings" %}
{% include "header.html" %}
{% endwith %}
<body>
{% include "navbar.html" %}
<div class="container-fluid">
{% include "sidebar.html" %}
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="setting-container mt-4">
{% if message != "" %}
<div class="alert alert-{{ status }}" role="alert">
{{ message }}
</div>
{% endif %}
<h1 class="">Settings</h1>
<hr>
<div class="card mb-3">
<h6 class="card-header">Dashboard Theme</h6>
<div class="card-body">
<div class="row">
<div class="col-6">
<button class='btn btn-outline-primary theme-switch-btn {% if session["theme"] == "light" %} {{ "active" }} {% endif %}' data-theme="light">
<i class="bi bi-sun-fill"></i>
Light
</button>
</div>
<div class="col-6">
<button class='btn btn-outline-primary theme-switch-btn {% if session["theme"] == "dark" %} {{ "active" }} {% endif %}' data-theme="dark">
<i class="bi bi-moon-fill"></i>
Dark
</button>
</div>
</div>
</div>
</div>
<hr>
{% if required_auth == "true" %}
<div class="card mb-3">
<h6 class="card-header">Peer Default Settings</h6>
<div class="card-body">
<form action="/update_peer_default_config" method="post">
<div class="form-group">
<div class="row">
<div class="col-sm-6">
<label for="peer_global_DNS">DNS</label>
<input type="text" class="form-control mb-4" id="peer_global_DNS"
name="peer_global_DNS"
value="{{ peer_global_DNS }}" required>
</div>
<div class="col-sm-6">
<label for="peer_endpoint_allowed_ip">Peer Endpoint Allowed IPs</label>
<input type="text" class="form-control mb-4" id="peer_endpoint_allowed_ip"
name="peer_endpoint_allowed_ip"
value="{{ peer_endpoint_allowed_ip }}" required>
</div>
<div class="col-sm-6">
<label for="peer_mtu">MTU</label>
<input type="text" class="form-control mb-4" id="peer_mtu"
name="peer_mtu"
value="{{ peer_mtu }}">
</div>
<div class="col-sm-6">
<label for="peer_keep_alive">Persistent Keepalive</label>
<input type="text" class="form-control mb-4" id="peer_keep_alive"
name="peer_keep_alive"
value="{{ peer_keepalive }}">
</div>
<div class="col-sm-12">
<label for="peer_remote_endpoint"><strong>Peer Remote Endpoint (This will be change globally, and will be apply to all peer's QR code and configuration file.)</strong></label>
<input type="text" class="form-control mb-4" id="peer_remote_endpoint"
name="peer_remote_endpoint"
value="{{ peer_remote_endpoint }}" required>
</div>
</div>
<button class="btn btn-success" type="submit">Update Peer Default Settings</button>
</div>
</form>
</div>
</div>
<hr>
<div class="card mb-3">
<h6 class="card-header">WireGuard Configuration Path</h6>
<div class="card-body">
<form action="/update_wg_conf_path" method="post" class="update_wg_conf_path">
<div class="form-group">
<label for="wg_conf_path">Path</label>
<input type="text" class="form-control mb-2" id="wg_conf_path" name="wg_conf_path"
value="{{ wg_conf_path }}">
<p class="text-muted">Remember to remove <code>/</code> at the end of your path. e.g <code>/etc/wireguard</code>
</p>
<button class="btn btn-danger change_path">Update Path & Restart Dashboard</button>
</div>
</form>
</div>
</div>
<div class="card mb-3">
<h6 class="card-header">Account</h6>
<div class="card-body">
<form action="/update_acct" method="post">
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control mb-4" id="username" name="username"
value="{{ session['username'] }}" required>
<button type="submit" class="btn btn-danger">Update Account</button>
</div>
</form>
</div>
</div>
<div class="card mb-3">
<h6 class="card-header">Security</h6>
<div class="card-body">
<form action="/update_pwd" method="post">
<div class="form-group">
<label for="currentpass">Current Password</label>
<input type="password" class="form-control mb-2" id="currentpass" name="currentpass">
<label for="newpass">New Password</label>
<input type="password" class="form-control mb-2" id="newpass" name="newpass">
<label for="repnewpass">Repeat New Password</label>
<input type="password" class="form-control mb-4" id="repnewpass" name="repnewpass">
<button type="submit" class="btn btn-danger">Update Password</button>
</div>
</form>
</div>
</div>
{% endif %}
<div class="card">
<h6 class="card-header">Dashboard Configuration</h6>
<div class="card-body">
<form action="/update_app_ip_port" method="post" class="update_app_ip_port">
<div class="form-group">
<div class="row">
<div class="col-sm">
<label for="app_ip">Dashboard IP</label>
<input type="text" class="form-control mb-2" id="app_ip" name="app_ip" value="{{ app_ip }}">
<p><small class="text-danger mb-4">0.0.0.0 means it can be access by anyone with your server
IP Address.</small></p>
</div>
<div class="col-sm">
<label for="app_port">Dashboard Port</label>
<input type="text" class="form-control mb-4" id="app_port" name="app_port"
value="{{ app_port }}">
</div>
</div>
<button type="button" class="btn btn-danger confirm_modal" data-toggle="modal"
data-target="#confirmModal">Update Configuration & Restart Dashboard
</button>
</div>
</form>
</div>
</div>
</div>
</main>
<!-- Modal -->
<div class="modal fade" id="confirmModal" data-backdrop="static" data-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Confirm Dashboard Configuration</h5>
</div>
<div class="modal-body">
<small>Dashboard Original IP</small>
<p>{{ app_ip }}</p>
<small style="font-weight: bold" class="text-bold">Dashboard New IP</small>
<p class="app_new_ip text-bold text-danger" style="font-weight: bold"></p>
<small>Dashboard Original Port</small>
<p>{{ app_port }}</p>
<small style="font-weight: bold" class="text-bold">Dashboard New Port</small>
<p class="app_new_port text-bold text-danger" style="font-weight: bold"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary cancel_restart" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger confirm_restart">Confirm & Restart Dashboard</button>
</div>
</div>
</div>
</div>
</div>
{% include "tools.html" %}
<div class="position-fixed top-0 right-0 p-3 toastContainer" style="z-index: 5; right: 0; top: 50px;"></div>
</body>
{% include "footer.html" %}
<script src="{{ url_for('static',filename='js/settings.js') }}"></script>
</html>

View File

@ -1,120 +0,0 @@
<div class="bottomNavWrapper"></div>
<div class="bottom">
<nav class="navbar navbar-dark fixed-bottom bg-light flex-md-nowrap p-0 bottomNav">
<div class="bottomNavContainer" style="z-index: 1000;">
<div class="bottomNavButton bottomNavHome">
<i class="bi bi-house"></i>Home
</div>
<div class="bottomNavButton bottomNavConfigs">
<i class="bi bi-files"></i>
Configs
<div class="subNav bg-light animate__animated">
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Configurations</span>
</h6>
<ul class="nav flex-column">
{% for i in conf%}
<li class="nav-item"><a class="nav-link nav-conf-link sb-{{i['conf']}}-url" href="/configuration/{{i['conf']}}" data-conf-id="{{i['conf']}}"><samp>{{i['conf']}}</samp></a></li>
{%endfor%}
</ul>
<hr>
</div>
</div>
<div class="bottomNavButton bottomNavSettings">
<i class="bi bi-gear"></i>
Settings
</div>
<div class="bottomNavButton bottomNavMore">
<i class="bi bi-justify"></i>More
<div class="subNav bg-light animate__animated">
<ul class="nav flex-column">
{% if session['update'] == "true" %}
<li class="nav-item sb-update-li">
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>New Update</span>
</h6>
<a class="nav-link sb-update-url text-success" href="https://github.com/donaldzou/WGDashboard#-how-to-update-the-dashboard">
{{ session['updateInfo']['name'] }} -
<code>{{ session['updateInfo']['tag_name'] }}</code>
</a>
</li>
{% endif %}
</ul>
<hr>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Tools</span>
</h6>
<ul class="nav flex-column">
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link" data-toggle="modal" data-target="#ping_modal" href="#">Ping</a></li>
<li class="nav-item"><a class="nav-link" data-toggle="modal" data-target="#traceroute_modal" href="#">Traceroute</a></li>
</ul>
</ul>
<hr>
{% if "username" in session %}
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link text-danger" href="/signout" style="font-weight: bold">Sign Out</a></li>
</ul>
{% endif %}
<ul class="nav flex-column">
<li class="nav-item"><a href="https://github.com/donaldzou/WGDashboard/releases/tag/{{ session['dashboard_version'] }}"><small class="nav-link text-muted">{{ session['dashboard_version'] }}</small></a></li>
</ul>
</div>
</div>
</div>
</nav>
</div>
<div class="row">
<div class="row">
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
<div class="sidebar-sticky pt-3">
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link sb-home-url" href="/">Home</a></li>
{% if "username" in session %}
<li class="nav-item"><a class="nav-link sb-settings-url" href="/settings">Settings</a></li>
{% endif %}
{% if session['update'] == "true" %}
<li class="nav-item sb-update-li">
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>New Update</span>
</h6>
<a class="nav-link sb-update-url text-success" href="https://github.com/donaldzou/WGDashboard#-how-to-update-the-dashboard">
{{ session['updateInfo']['name'] }} -
<code>{{ session['updateInfo']['tag_name'] }}</code>
</a>
</li>
{% endif %}
</ul>
<hr>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Configurations</span>
</h6>
<ul class="nav flex-column">
{% for i in conf%}
<li class="nav-item"><a class="nav-link nav-conf-link sb-{{i['conf']}}-url" href="/configuration/{{i['conf']}}" data-conf-id="{{i['conf']}}"><samp>{{i['conf']}}</samp></a></li>
{%endfor%}
</ul>
<hr>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Tools</span>
</h6>
<ul class="nav flex-column">
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link" data-toggle="modal" data-target="#ping_modal" href="#">Ping</a></li>
<li class="nav-item"><a class="nav-link" data-toggle="modal" data-target="#traceroute_modal" href="#">Traceroute</a></li>
</ul>
</ul>
<hr>
{% if "username" in session %}
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link text-danger" href="/signout" style="font-weight: bold">Sign Out</a></li>
</ul>
{% endif %}
<ul class="nav flex-column">
<li class="nav-item"><a href="https://github.com/donaldzou/WGDashboard/releases/tag/{{ session['dashboard_version'] }}"><small class="nav-link text-muted">{{ session['dashboard_version'] }}</small></a></li>
</ul>
</div>
</nav>
</div>
</div>

View File

@ -1,65 +0,0 @@
<html>
{% with title="Sign In"%}
{% include "header.html"%}
{% endwith %}
<style>
.login-container-fluid{
display: flex;
height: calc( 100% - 240px );
align-items: center;
}
</style>
<body>
{% include "navbar.html" %}
<div id="login"></div>
<small class="text-muted" style="position: fixed; bottom: 0; width: 100%; text-align: center; margin-bottom: 2rem">Version: {{ version }}</small>
</body>
{% include "footer.html" %}
<script>
let loginButton = $('button[type="submit"]');
loginButton.on("click", function(e){
e.preventDefault();
let $password = $("#password");
let $username = $("#username");
let req = [$password, $username];
let check = true
for (let i = 0; i < req.length; i++){
if ($(req[i]).val().length === 0){
loginButton.html("Sign In");
check = false;
$(req[i]).addClass("is-invalid");
break;
}
}
if (check){
$(this).html("Signing In...").attr("disabled", "disabled");
$.ajax({
url: "/auth",
method: "POST",
headers:{"Content-Type": "application/json"},
data: JSON.stringify({
"username": $("#username").val(),
"password": $("#password").val()
})
}).done(function(res){
if (res.status === true){
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get("redirect")){
if (document.URL.substring(0, 5) == "http:"){
window.location.replace(`http://${urlParams.get("redirect")}`)
}else if (document.URL.substring(0, 5) == "https"){
window.location.replace(`https://${urlParams.get("redirect")}`)
}
}else{
window.location.replace("/");
}
}else{
$(".alert").html(res.msg).removeClass("d-none").fadeIn();
loginButton.html("Sign In").removeAttr("disabled");
$("input[required]").addClass("is-invalid");
}
});
}
});
</script>
</html>

View File

@ -1,121 +0,0 @@
<div class="modal fade" id="ping_modal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Ping</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm">
<div class="mb-3">
<small>Configuration</small>
<select class="form-control mt-2 conf_dropdown">
<option value="none" selected="selected" disabled>Select Configuration</option>
{% for i in conf%}
<option value="{{ i['conf'] }}">{{ i['conf'] }}</option>
{%endfor%}
</select>
</div>
</div>
<div class="col-sm">
<div class="mb-3">
<small>IP</small>
<select class="form-control mt-2 ip_dropdown">
<option value="none" selected="selected" disabled>Choose an IP</option>
</select>
</div>
</div>
<div class="col-sm">
<div class="mb-3">
<small>Ping Count</small>
<input type="number" class="form-control mt-2 ping_count" min=1 value=4>
</div>
</div>
</div>
<hr>
<div class="ping_result">
<table class="table">
<tbody></tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary send_ping" disabled>Ping</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="traceroute_modal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Traceroute</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm">
<div class="mb-3">
<small>Configuration</small>
<select class="form-control mt-2 conf_dropdown">
<option value="none" selected="selected" disabled>Select Configuration</option>
{% for i in conf%}
<option value="{{ i['conf'] }}">{{ i['conf'] }}</option>
{%endfor%}
</select>
</div>
</div>
<div class="col-sm">
<div class="mb-3">
<small>IP</small>
<select class="form-control mt-2 ip_dropdown">
<option value="none" selected="selected" disabled>Choose an IP</option>
</select>
</div>
</div>
</div>
<button class="btn btn-primary send_traceroute" disabled>Traceroute</button>
<hr>
<div class="traceroute_result">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Hop</th>
<th scope="col">IP</th>
<th scope="col">Avg RTT</th>
<th scope="col">Min RTT</th>
<th scope="col">Max RTT</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="update_modal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">How to update dashboard</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<pre><code>$ sudo sh wgd.sh stop</code><br><code>$ sudo sh wgd.sh update</code><br><code>$ sudo sh wgd.sh start</code></pre>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>