mirror of
https://github.com/Sebclem/hassio-nextcloud-backup.git
synced 2024-11-22 17:22:58 +01:00
🔨 Move loading modal and toast to bootstrap
This commit is contained in:
parent
59afab1120
commit
8328786df8
@ -24,16 +24,31 @@ app.use(express.urlencoded({ extended: false }));
|
|||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.static(path.join(__dirname, "public")));
|
app.use(express.static(path.join(__dirname, "public")));
|
||||||
|
|
||||||
// Boootstrap JS Files
|
|
||||||
app.use('/js/', express.static(path.join(__dirname, '/node_modules/bootstrap/dist/js')))
|
|
||||||
// Fontawesome files
|
|
||||||
app.use('/css/', express.static(path.join(__dirname, '/node_modules/@fortawesome/fontawesome-free/css')))
|
|
||||||
app.use('/webfonts/', express.static(path.join(__dirname, '/node_modules/@fortawesome/fontawesome-free/webfonts')))
|
|
||||||
|
|
||||||
|
|
||||||
app.use("/", indexRouter);
|
app.use("/", indexRouter);
|
||||||
app.use("/api", apiRouter);
|
app.use("/api", apiRouter);
|
||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------
|
||||||
|
Library statics
|
||||||
|
----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Boootstrap JS Files
|
||||||
|
app.use('/js/bootstrap.min.js', express.static(path.join(__dirname, '/node_modules/bootstrap/dist/js/bootstrap.min.js')))
|
||||||
|
|
||||||
|
|
||||||
|
// Fontawesome Files
|
||||||
|
app.use('/css/fa-all.min.css', express.static(path.join(__dirname, '/node_modules/@fortawesome/fontawesome-free/css/all.min.css')))
|
||||||
|
app.use('/webfonts/', express.static(path.join(__dirname, '/node_modules/@fortawesome/fontawesome-free/webfonts')))
|
||||||
|
|
||||||
|
// Jquery JS Files
|
||||||
|
app.use('/js/jquery.min.js', express.static(path.join(__dirname, '/node_modules/jquery/dist/jquery.min.js')))
|
||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------
|
||||||
|
Error handler
|
||||||
|
----------------------------------------------------------
|
||||||
|
*/
|
||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
next(createError(404));
|
next(createError(404));
|
||||||
@ -50,6 +65,12 @@ app.use(function (err, req, res, next) {
|
|||||||
res.render("error");
|
res.render("error");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------
|
||||||
|
Init app
|
||||||
|
----------------------------------------------------------
|
||||||
|
*/
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const newlog = require("./config/winston");
|
const newlog = require("./config/winston");
|
||||||
if (!fs.existsSync("/data")) fs.mkdirSync("/data");
|
if (!fs.existsSync("/data")) fs.mkdirSync("/data");
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,16 +17,10 @@
|
|||||||
"form-data": "^3.0.0",
|
"form-data": "^3.0.0",
|
||||||
"got": "^11.8.1",
|
"got": "^11.8.1",
|
||||||
"http-errors": "~1.6.3",
|
"http-errors": "~1.6.3",
|
||||||
|
"jquery": "^3.5.1",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"morgan": "~1.9.1",
|
"morgan": "~1.9.1",
|
||||||
"webdav": "^3.6.2",
|
"webdav": "^3.6.2",
|
||||||
"winston": "^3.3.3"
|
"winston": "^3.3.3"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^7.17.0",
|
|
||||||
"eslint-config-eslint": "^6.0.0",
|
|
||||||
"eslint-config-prettier": "^6.15.0",
|
|
||||||
"eslint-plugin-import": "^2.22.1",
|
|
||||||
"eslint-plugin-node": "^11.1.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,18 @@
|
|||||||
background-color: #0091ea ;
|
background-color: #0091ea ;
|
||||||
}
|
}
|
||||||
#header-box{
|
#header-box{
|
||||||
min-height: 150px;
|
min-height: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn .bi::before{
|
.btn .bi::before{
|
||||||
vertical-align: middle ;
|
vertical-align: middle ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.toast-container {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1055;
|
||||||
|
margin: 5px;
|
||||||
|
top: 58px;
|
||||||
|
right: 0;
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,30 @@
|
|||||||
|
function create_toast(type, message, delay) {
|
||||||
|
let toast_class;
|
||||||
|
let icon_class;
|
||||||
|
switch (type) {
|
||||||
|
case 'error':
|
||||||
|
toast_class = 'bg-danger';
|
||||||
|
icon_class = 'fa-exclamation-triangle'
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
toast_class = `bg-${type}`
|
||||||
|
icon_class = 'fa-check'
|
||||||
|
}
|
||||||
|
let toast_id = Date.now().toString();
|
||||||
|
let toast_html = `<div id="${toast_id}" class="toast d-flex align-items-center text-white ${toast_class}" role="alert" aria-live="assertive" aria-atomic="true">`
|
||||||
|
toast_html += `<div class="toast-body h5 mb-0"><i class="fas ${icon_class} me-2"></i> ${message}</div>`
|
||||||
|
toast_html += `<button type="button" class="btn-close btn-close-white ms-auto me-2" data-bs-dismiss="toast" aria-label="Close"></button></div>`
|
||||||
|
$('#toast-container').prepend(toast_html);
|
||||||
|
let toast_dom = document.getElementById(toast_id)
|
||||||
|
let toast = new bootstrap.Toast(toast_dom, {
|
||||||
|
animation: true,
|
||||||
|
autohide: delay !== -1,
|
||||||
|
delay: delay
|
||||||
|
});
|
||||||
|
toast_dom.addEventListener('hidden.bs.toast', function () {
|
||||||
|
this.remove();
|
||||||
|
});
|
||||||
|
toast.show();
|
||||||
|
return toast;
|
||||||
|
}
|
@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
<link rel='stylesheet' href='./css/style.css'/>
|
<link rel='stylesheet' href='./css/style.css'/>
|
||||||
<link rel="stylesheet" href="./css/custom_bootstrap.css">
|
<link rel="stylesheet" href="./css/custom_bootstrap.css">
|
||||||
<link rel="stylesheet" href="./css/all.css">
|
<link rel="stylesheet" href="./css/fa-all.min.css">
|
||||||
|
<!-- <link rel="stylesheet" href="./css/toast.min.css">-->
|
||||||
<!-- <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">-->
|
<!-- <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">-->
|
||||||
<!-- <style>-->
|
<!-- <style>-->
|
||||||
<!-- .modal input[disabled] {-->
|
<!-- .modal input[disabled] {-->
|
||||||
@ -140,13 +141,13 @@
|
|||||||
<div class="col-12 col-md-3">
|
<div class="col-12 col-md-3">
|
||||||
<div class="card text-white bg-dark h-100 shadow border-secondary">
|
<div class="card text-white bg-dark h-100 shadow border-secondary">
|
||||||
<div class="card-header fw-bold h5 border-secondary border-bottom">Manual</div>
|
<div class="card-header fw-bold h5 border-secondary border-bottom">Manual</div>
|
||||||
<div class="card-body py-2">
|
<div class="card-body">
|
||||||
<div class="center w-100">
|
<div class="w-100">
|
||||||
<a class="btn btn-success" id="btn-backup-now" style="margin-top: 7px; display: block;">
|
<a class="btn btn-success d-block mb-2" id="btn-backup-now">
|
||||||
Backup Now
|
Backup Now
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-danger" id="btn-clean-now" style="margin-top: 7px; display: block;">
|
<a class="btn btn-danger d-block" id="btn-clean-now"">
|
||||||
Clean Now
|
Clean Now
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -167,7 +168,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-12 col-lg-6 ">
|
<div class="col-12 col-md-12 col-lg-6 ">
|
||||||
<div class="card text-white bg-dark h-100 shadow border-secondary">
|
<div class="card text-white bg-dark h-100 shadow border-secondary">
|
||||||
<div class="card-header fw-bold h4 text-center border-secondary border-bottom">Snapshots in Nextcloud</div>
|
<div class="card-header fw-bold h4 text-center border-secondary border-bottom">Snapshots in Nextcloud
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title text-center fw-bold border-bottom border-secondary pb-3">Auto</h5>
|
<h5 class="card-title text-center fw-bold border-bottom border-secondary pb-3">Auto</h5>
|
||||||
<div id="auto_backups"></div>
|
<div id="auto_backups"></div>
|
||||||
@ -183,95 +185,31 @@
|
|||||||
|
|
||||||
<%- include('modals/nextcloud-settings-modal') %>
|
<%- include('modals/nextcloud-settings-modal') %>
|
||||||
<%- include('modals/backup-settings-modal') %>
|
<%- include('modals/backup-settings-modal') %>
|
||||||
|
<%- include('modals/loading-modal') %>
|
||||||
<div id="modal-loading" class="modal blue-grey darken-4 white-text">
|
<div id="toast-container" class="toast-container" aria-live="polite" aria-atomic="true">
|
||||||
<div class="modal-content ">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col s12 center">
|
|
||||||
<h4>Loading</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row valign-wrapper" style="height: 150px;">
|
|
||||||
<div class="col s12 center">
|
|
||||||
<div class="preloader-wrapper big active">
|
|
||||||
<div class="spinner-layer spinner-blue">
|
|
||||||
<div class="circle-clipper left">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="gap-patch">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="circle-clipper right">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="spinner-layer spinner-red">
|
|
||||||
<div class="circle-clipper left">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="gap-patch">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="circle-clipper right">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="spinner-layer spinner-yellow">
|
|
||||||
<div class="circle-clipper left">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="gap-patch">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="circle-clipper right">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="spinner-layer spinner-green">
|
|
||||||
<div class="circle-clipper left">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="gap-patch">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
<div class="circle-clipper right">
|
|
||||||
<div class="circle"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script src="./js/bootstrap.min.js"></script>
|
<script src="./js/bootstrap.min.js"></script>
|
||||||
<script src="./js/jquery-3.4.1.min.js"></script>
|
<script src="./js/jquery.min.js"></script>
|
||||||
<script src="./js/index.js"></script>
|
<script src="./js/index.js"></script>
|
||||||
|
<script src="./js/toast.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var last_status = "";
|
var last_status = "";
|
||||||
var last_local_snap = "";
|
var last_local_snap = "";
|
||||||
var last_manu_back = "";
|
var last_manu_back = "";
|
||||||
var last_auto_back = "";
|
var last_auto_back = "";
|
||||||
|
|
||||||
|
const default_toast_timeout = 10000;
|
||||||
var loadingModal = null;
|
var loadingModal = null;
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
$.ajaxSetup({ traditional: true });
|
$.ajaxSetup({ traditional: true });
|
||||||
updateLocalSnaps();
|
updateLocalSnaps();
|
||||||
update_status();
|
update_status();
|
||||||
let tooltips = document.querySelectorAll('.tooltipped');
|
loadingModal = new bootstrap.Modal(document.getElementById('loading-modal'), {
|
||||||
M.Tooltip.init(tooltips, {});
|
keyboard: false,
|
||||||
let drops = document.querySelectorAll('.dropdown-trigger');
|
backdrop: 'static'
|
||||||
M.Dropdown.init(drops, {
|
|
||||||
constrainWidth: false,
|
|
||||||
coverTrigger: false,
|
|
||||||
alignment: 'right',
|
|
||||||
onOpenStart: () => $('#setting-trigger').addClass('active'),
|
|
||||||
onCloseEnd: () => $('#setting-trigger').removeClass('active')
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(update_status, 500);
|
setInterval(update_status, 500);
|
||||||
@ -281,15 +219,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function updateDynamicListeners() {
|
function updateDynamicListeners() {
|
||||||
var elems = document.querySelectorAll('.collapsible');
|
|
||||||
M.Collapsible.init(elems, { accordion: true });
|
|
||||||
var modals = document.querySelectorAll('.modal:not(#modal-loading)');
|
|
||||||
M.Modal.init(modals, { dismissible: true });
|
|
||||||
|
|
||||||
let loadingModals = document.querySelectorAll('#modal-loading');
|
|
||||||
M.Modal.init(loadingModals, { dismissible: false });
|
|
||||||
|
|
||||||
loadingModal = M.Modal.getInstance(document.querySelector('#modal-loading'));
|
|
||||||
$('.local-snap-listener').click(function () {
|
$('.local-snap-listener').click(function () {
|
||||||
let id = this.getAttribute('data-id');
|
let id = this.getAttribute('data-id');
|
||||||
console.log(id);
|
console.log(id);
|
||||||
@ -476,17 +405,12 @@
|
|||||||
$.post('./api/restore', { path: id })
|
$.post('./api/restore', { path: id })
|
||||||
.done((data) => {
|
.done((data) => {
|
||||||
console.log("Restore cmd send !");
|
console.log("Restore cmd send !");
|
||||||
M.toast({
|
create_toast("success", "Command send !", default_toast_timeout);
|
||||||
html: '<i class="material-icons" style="margin-right:10px">check_box</i> Command send !',
|
})
|
||||||
classes: "green"
|
.fail((error) => {
|
||||||
});
|
console.log(error);
|
||||||
}).fail((error) => {
|
create_toast("error", "Can't send command !", default_toast_timeout);
|
||||||
console.log(error);
|
})
|
||||||
M.toast({
|
|
||||||
html: '<i class="material-icons" style="margin-right:10px">warning</i> Can\'t send command !',
|
|
||||||
classes: "red"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.always(() => loadingModal.close())
|
.always(() => loadingModal.close())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,29 +433,24 @@
|
|||||||
.done((data) => {
|
.done((data) => {
|
||||||
console.log('Saved');
|
console.log('Saved');
|
||||||
$('#nextcloud_settings_message').parent().addClass("hide");
|
$('#nextcloud_settings_message').parent().addClass("hide");
|
||||||
M.toast({
|
create_toast("success", "Nextcloud settings saved !", default_toast_timeout);
|
||||||
html: '<i class="material-icons" style="margin-right:10px">check_box</i> Nextcloud settings saved !',
|
|
||||||
classes: "green"
|
|
||||||
});
|
|
||||||
M.Modal.getInstance(document.querySelector('#modal-settings-nextcloud')).close();
|
M.Modal.getInstance(document.querySelector('#modal-settings-nextcloud')).close();
|
||||||
|
|
||||||
}).fail((data) => {
|
})
|
||||||
debugger;
|
.fail((data) => {
|
||||||
if (data.status == 406) {
|
debugger;
|
||||||
console.log(data.responseJSON.message);
|
if (data.status == 406) {
|
||||||
$('#nextcloud_settings_message').html(data.responseJSON.message);
|
console.log(data.responseJSON.message);
|
||||||
|
$('#nextcloud_settings_message').html(data.responseJSON.message);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$('#nextcloud_settings_message').html("Invalid Settings.");
|
$('#nextcloud_settings_message').html("Invalid Settings.");
|
||||||
|
|
||||||
}
|
}
|
||||||
$('#nextcloud_settings_message').parent().removeClass("hide");
|
$('#nextcloud_settings_message').parent().removeClass("hide");
|
||||||
M.toast({
|
create_toast("error", "Invalid Nextcloud settings !", default_toast_timeout);
|
||||||
html: '<i class="material-icons" style="margin-right:10px">warning</i> Invalid Nextcloud settings !',
|
console.log('Fail');
|
||||||
classes: "red"
|
}).always(() => {
|
||||||
});
|
|
||||||
console.log('Fail');
|
|
||||||
}).always(() => {
|
|
||||||
loadingModal.close();
|
loadingModal.close();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -540,17 +459,12 @@
|
|||||||
$.post('./api/manual-backup?id=' + id + '&name=' + name)
|
$.post('./api/manual-backup?id=' + id + '&name=' + name)
|
||||||
.done((data) => {
|
.done((data) => {
|
||||||
console.log("manual bk cmd send !");
|
console.log("manual bk cmd send !");
|
||||||
M.toast({
|
create_toast("success", "Command send !", default_toast_timeout);
|
||||||
html: '<i class="material-icons" style="margin-right:10px">check_box</i> Command send !',
|
})
|
||||||
classes: "green"
|
.fail((error) => {
|
||||||
});
|
console.log(error);
|
||||||
}).fail((error) => {
|
create_toast("error", "Can't send command !", default_toast_timeout);
|
||||||
console.log(error);
|
})
|
||||||
M.toast({
|
|
||||||
html: '<i class="material-icons" style="margin-right:10px">warning</i> Can\'t send command !',
|
|
||||||
classes: "red"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,17 +498,12 @@
|
|||||||
loadingModal.open();
|
loadingModal.open();
|
||||||
$.post('./api/new-backup')
|
$.post('./api/new-backup')
|
||||||
.done(() => {
|
.done(() => {
|
||||||
M.toast({
|
create_toast("success", "Command send !", default_toast_timeout);
|
||||||
html: '<i class="material-icons" style="margin-right:10px">check_box</i> Command send !',
|
})
|
||||||
classes: "green"
|
.fail((error) => {
|
||||||
});
|
console.log(error);
|
||||||
}).fail((error) => {
|
create_toast("error", "Can't send command !", default_toast_timeout);
|
||||||
console.log(error);
|
})
|
||||||
M.toast({
|
|
||||||
html: '<i class="material-icons" style="margin-right:10px">warning</i> Can\'t send command !',
|
|
||||||
classes: "red"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.always(() => {
|
.always(() => {
|
||||||
loadingModal.close();
|
loadingModal.close();
|
||||||
})
|
})
|
||||||
@ -604,17 +513,12 @@
|
|||||||
loadingModal.open();
|
loadingModal.open();
|
||||||
$.post('./api/clean-now')
|
$.post('./api/clean-now')
|
||||||
.done(() => {
|
.done(() => {
|
||||||
M.toast({
|
create_toast("success", "Command send !", default_toast_timeout);
|
||||||
html: '<i class="material-icons" style="margin-right:10px">check_box</i> Command send !',
|
})
|
||||||
classes: "green"
|
.fail((error) => {
|
||||||
});
|
console.log(error);
|
||||||
}).fail((error) => {
|
create_toast("error", "Can't send command !", default_toast_timeout);
|
||||||
console.log(error);
|
})
|
||||||
M.toast({
|
|
||||||
html: '<i class="material-icons" style="margin-right:10px">warning</i> Can\'t send command !',
|
|
||||||
classes: "red"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.always(() => {
|
.always(() => {
|
||||||
loadingModal.close();
|
loadingModal.close();
|
||||||
})
|
})
|
||||||
@ -762,17 +666,16 @@
|
|||||||
exclude_folder: exclude_folder
|
exclude_folder: exclude_folder
|
||||||
})
|
})
|
||||||
.done(() => {
|
.done(() => {
|
||||||
M.toast({
|
create_toast("success", "Backup settings saved !", default_toast_timeout);
|
||||||
html: '<i class="material-icons" style="margin-right:10px">check_box</i> Backup settings saved !',
|
|
||||||
classes: "green"
|
|
||||||
});
|
|
||||||
M.Modal.getInstance(document.querySelector('#modal-settings-backup')).close();
|
M.Modal.getInstance(document.querySelector('#modal-settings-backup')).close();
|
||||||
}).fail(() => {
|
})
|
||||||
M.toast({
|
.fail(() => {
|
||||||
html: '<i class="material-icons" style="margin-right:10px">warning</i> Can\'t save backup settings !',
|
create_toast("error", "Can't save backup settings !", default_toast_timeout);
|
||||||
classes: "red"
|
M.toast({
|
||||||
});
|
html: '<i class="material-icons" style="margin-right:10px">warning</i> Can\'t save backup settings !',
|
||||||
}).always(() => {
|
classes: "red"
|
||||||
|
});
|
||||||
|
}).always(() => {
|
||||||
loadingModal.close();
|
loadingModal.close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
<div class="modal" id="loading-modal" tabindex="-1"
|
||||||
|
aria-hidden="true">
|
||||||
|
<div class="modal-dialog border-secondary">
|
||||||
|
<div class="modal-content bg-dark text-white">
|
||||||
|
<div class="modal-header border-secondary d-flex justify-content-center">
|
||||||
|
<h3 class="modal-title fw-bold">Loading</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<div class="spinner-border text-accent border-5" style="width: 5rem; height: 5rem" role="status">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user