Added spinner and fixed asset delete bug
All checks were successful
Build and Publish Docker Image / build (push) Successful in 39s
All checks were successful
Build and Publish Docker Image / build (push) Successful in 39s
This commit is contained in:
parent
85086c0077
commit
4f5c5fd09d
8 changed files with 314 additions and 98 deletions
|
@ -4,7 +4,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-container">
|
||||
<form method="POST" enctype="multipart/form-data" class="form">
|
||||
<form method="POST" enctype="multipart/form-data" class="form" id="assetForm">
|
||||
<div class="form-group">
|
||||
<label for="title" class="form-label">Title</label>
|
||||
<input
|
||||
|
@ -82,7 +82,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="button button-primary">
|
||||
<button type="submit" class="button button-primary" id="submitBtn">
|
||||
<i class="fas fa-save"></i> Save Asset
|
||||
</button>
|
||||
<a href="{{ url_for('index') }}" class="button button-secondary">
|
||||
|
@ -115,8 +115,11 @@
|
|||
"https://cdnjs.cloudflare.com/ajax/libs/Trumbowyg/2.27.3/ui/icons.svg",
|
||||
});
|
||||
|
||||
// File input preview handling
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const form = document.getElementById("assetForm");
|
||||
const loadingOverlay = document.querySelector(".loading-overlay");
|
||||
const loadingText = document.querySelector(".loading-text");
|
||||
|
||||
// Featured image preview
|
||||
const featuredInput = document.getElementById("featured_image");
|
||||
const featuredPreview = document.querySelector(".file-input-preview");
|
||||
|
@ -152,6 +155,45 @@
|
|||
`;
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(form);
|
||||
loadingOverlay.style.display = "flex";
|
||||
loadingText.textContent = "Processing...";
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "{{ url_for('add_asset') }}", true);
|
||||
|
||||
xhr.onload = function() {
|
||||
if (xhr.status === 200) {
|
||||
const response = JSON.parse(xhr.responseText);
|
||||
if (response.success) {
|
||||
window.location.href = response.redirect;
|
||||
} else {
|
||||
loadingText.textContent = "Failed: " + response.error;
|
||||
setTimeout(() => {
|
||||
loadingOverlay.style.display = "none";
|
||||
}, 2000);
|
||||
}
|
||||
} else {
|
||||
loadingText.textContent = "Upload failed! Please try again.";
|
||||
setTimeout(() => {
|
||||
loadingOverlay.style.display = "none";
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = function() {
|
||||
loadingText.textContent = "Network error! Please try again.";
|
||||
setTimeout(() => {
|
||||
loadingOverlay.style.display = "none";
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
xhr.send(formData);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -78,19 +78,6 @@
|
|||
<i class="fas fa-file"></i>
|
||||
{{ file.original_filename or file.filename }}
|
||||
</a>
|
||||
<form
|
||||
method="POST"
|
||||
action="{{ url_for('delete_asset_file', id=file.id) }}"
|
||||
class="inline-form"
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
class="button button-small button-danger"
|
||||
onclick="return confirm('Are you sure you want to delete this file?')"
|
||||
>
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
|
@ -27,11 +27,47 @@
|
|||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<style>
|
||||
.loading-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
z-index: 9999;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.loading-spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 5px solid #f3f3f3;
|
||||
border-top: 5px solid #3498db;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.loading-text {
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
}
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Trumbowyg/2.27.3/trumbowyg.min.js"></script>
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div class="loading-overlay">
|
||||
<div class="loading-spinner"></div>
|
||||
<div class="loading-text">Processing...</div>
|
||||
</div>
|
||||
<nav class="main-nav">
|
||||
<div class="nav-container">
|
||||
<div class="nav-brand">Digital Assets Manager</div>
|
||||
|
@ -68,6 +104,5 @@
|
|||
});
|
||||
});
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-container">
|
||||
<form method="POST" enctype="multipart/form-data" class="form">
|
||||
<form method="POST" enctype="multipart/form-data" class="form" id="editAssetForm">
|
||||
<div class="form-group">
|
||||
<label for="title" class="form-label">Title</label>
|
||||
<input
|
||||
|
@ -90,7 +90,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="button button-primary">
|
||||
<button type="submit" class="button button-primary" id="submitBtn">
|
||||
<i class="fas fa-save"></i> Update Asset
|
||||
</button>
|
||||
<a
|
||||
|
@ -159,8 +159,11 @@
|
|||
"https://cdnjs.cloudflare.com/ajax/libs/Trumbowyg/2.27.3/ui/icons.svg",
|
||||
});
|
||||
|
||||
// File input preview handling (keeping your existing code)
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const form = document.getElementById("editAssetForm");
|
||||
const loadingOverlay = document.querySelector(".loading-overlay");
|
||||
const loadingText = document.querySelector(".loading-text");
|
||||
|
||||
// Featured image preview
|
||||
const featuredInput = document.getElementById("featured_image");
|
||||
const featuredPreview = document.querySelector(".file-input-preview");
|
||||
|
@ -196,6 +199,51 @@
|
|||
`;
|
||||
});
|
||||
});
|
||||
|
||||
// Handle form submission
|
||||
form.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(form);
|
||||
loadingOverlay.style.display = "flex";
|
||||
loadingText.textContent = "Processing...";
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "{{ url_for('edit_asset', id=asset.id) }}", true);
|
||||
|
||||
xhr.onload = function() {
|
||||
if (xhr.status === 200) {
|
||||
try {
|
||||
const response = JSON.parse(xhr.responseText);
|
||||
if (response.success) {
|
||||
window.location.href = response.redirect;
|
||||
} else {
|
||||
loadingText.textContent = "Failed: " + response.error;
|
||||
setTimeout(() => {
|
||||
loadingOverlay.style.display = "none";
|
||||
}, 2000);
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle non-JSON response (redirect)
|
||||
window.location.href = "{{ url_for('asset_detail', id=asset.id) }}";
|
||||
}
|
||||
} else {
|
||||
loadingText.textContent = "Update failed! Please try again.";
|
||||
setTimeout(() => {
|
||||
loadingOverlay.style.display = "none";
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = function() {
|
||||
loadingText.textContent = "Network error! Please try again.";
|
||||
setTimeout(() => {
|
||||
loadingOverlay.style.display = "none";
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
xhr.send(formData);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue