mirror of
https://github.com/LD-Reborn/Berufsschule_HAM.git
synced 2025-12-20 06:51:55 +00:00
Implemented frontend Locations update buttons
This commit is contained in:
@@ -67,7 +67,7 @@ public class LocationsController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Update")]
|
[HttpPost("Update")]
|
||||||
public async Task<bool> Update(LocationsModifyRequestModel requestModel)
|
public async Task<bool> Update([FromBody]LocationsModifyRequestModel requestModel)
|
||||||
{
|
{
|
||||||
if (requestModel is null)
|
if (requestModel is null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
namespace Berufsschule_HAM.Models;
|
namespace Berufsschule_HAM.Models;
|
||||||
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Berufsschule_HAM.Exceptions;
|
using Berufsschule_HAM.Exceptions;
|
||||||
public class LocationModel
|
public class LocationModel
|
||||||
{
|
{
|
||||||
@@ -22,8 +23,11 @@ public class LocationModel
|
|||||||
}
|
}
|
||||||
public class LocationsDescription
|
public class LocationsDescription
|
||||||
{
|
{
|
||||||
|
[JsonPropertyName("Location")]
|
||||||
public string? Location { get; set; }
|
public string? Location { get; set; }
|
||||||
|
[JsonPropertyName("RoomNumber")]
|
||||||
public string? RoomNumber { get; set; }
|
public string? RoomNumber { get; set; }
|
||||||
|
[JsonPropertyName("Seat")]
|
||||||
public string? Seat { get; set; }
|
public string? Seat { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Berufsschule_HAM.Models;
|
namespace Berufsschule_HAM.Models;
|
||||||
|
|
||||||
public class LocationsCreateRequestModel
|
public class LocationsCreateRequestModel
|
||||||
@@ -7,7 +9,9 @@ public class LocationsCreateRequestModel
|
|||||||
|
|
||||||
public class LocationsModifyRequestModel
|
public class LocationsModifyRequestModel
|
||||||
{
|
{
|
||||||
|
[JsonPropertyName("Location")]
|
||||||
public required string Location { get; set; }
|
public required string Location { get; set; }
|
||||||
|
[JsonPropertyName("Description")]
|
||||||
public required LocationsDescription Description { get; set; }
|
public required LocationsDescription Description { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,12 +38,20 @@
|
|||||||
<td>@locationTableViewModel.Seat</td>
|
<td>@locationTableViewModel.Seat</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
<button class="btn btn-sm btn-primary">Update</button>
|
<button class="btn btn-sm btn-warning btn-edit"
|
||||||
|
data-location-id="@locationTableViewModel.LocationID"
|
||||||
|
data-location-name="@locationTableViewModel.LocationName"
|
||||||
|
data-room-number="@locationTableViewModel.RoomNumber"
|
||||||
|
data-seat="@locationTableViewModel.Seat"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#editModal">
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
<button class="btn btn-sm btn-danger btn-delete"
|
<button class="btn btn-sm btn-danger btn-delete"
|
||||||
data-location-id="@locationTableViewModel.LocationID"
|
data-location-id="@locationTableViewModel.LocationID"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#deleteModal">
|
data-bs-target="#deleteModal">
|
||||||
🗑️ Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@@ -77,6 +85,35 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script defer>
|
||||||
|
|
||||||
|
function createToastContainer() {
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.id = 'toastContainer';
|
||||||
|
container.className = 'toast-container position-fixed bottom-0 end-0 p-3';
|
||||||
|
document.body.appendChild(container);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple toast helper
|
||||||
|
function showToast(message, type) {
|
||||||
|
const toastContainer = document.getElementById('toastContainer') || createToastContainer();
|
||||||
|
const toast = document.createElement('div');
|
||||||
|
toast.className = `toast align-items-center text-white bg-${type} border-0`;
|
||||||
|
toast.role = 'alert';
|
||||||
|
toast.innerHTML = `
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="toast-body">${message}</div>
|
||||||
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
toastContainer.appendChild(toast);
|
||||||
|
const bsToast = new bootstrap.Toast(toast, { delay: 3000 });
|
||||||
|
bsToast.show();
|
||||||
|
toast.addEventListener('hidden.bs.toast', () => toast.remove());
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const deleteModal = document.getElementById('deleteModal');
|
const deleteModal = document.getElementById('deleteModal');
|
||||||
@@ -161,3 +198,115 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- Location Edit Modal -->
|
||||||
|
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header bg-warning text-dark">
|
||||||
|
<h5 class="modal-title" id="editModalLabel">Edit Location</h5>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form id="editForm">
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" id="editLocationId" name="LocationID">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="editLocationName" class="form-label">Location Name</label>
|
||||||
|
<input type="text" class="form-control" id="editLocationName" name="LocationName" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="editRoomNumber" class="form-label">Room Number</label>
|
||||||
|
<input type="text" class="form-control" id="editRoomNumber" name="RoomNumber">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="editSeat" class="form-label">Seat</label>
|
||||||
|
<input type="text" class="form-control" id="editSeat" name="Seat">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-warning">Save changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// --- EDIT MODAL ---
|
||||||
|
const editModal = document.getElementById('editModal');
|
||||||
|
const editForm = document.getElementById('editForm');
|
||||||
|
|
||||||
|
editModal.addEventListener('show.bs.modal', event => {
|
||||||
|
const button = event.relatedTarget;
|
||||||
|
const id = button.getAttribute('data-location-id');
|
||||||
|
const name = button.getAttribute('data-location-name');
|
||||||
|
const room = button.getAttribute('data-room-number');
|
||||||
|
const seat = button.getAttribute('data-seat');
|
||||||
|
|
||||||
|
// Set values in the modal form
|
||||||
|
editForm.querySelector('#editLocationId').value = id;
|
||||||
|
editForm.querySelector('#editLocationName').value = name;
|
||||||
|
editForm.querySelector('#editRoomNumber').value = room;
|
||||||
|
editForm.querySelector('#editSeat').value = seat;
|
||||||
|
});
|
||||||
|
|
||||||
|
editForm.addEventListener('submit', async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
Location: editForm.editLocationId.value,
|
||||||
|
Description:
|
||||||
|
{
|
||||||
|
Location: editLocationName.value,
|
||||||
|
RoomNumber: editForm.editRoomNumber.value,
|
||||||
|
Seat: editForm.editSeat.value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/Locations/Update', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (result) {
|
||||||
|
const btn = document.querySelector(`button[data-location-id="${data.Location}"]`);
|
||||||
|
const row = btn.closest('tr');
|
||||||
|
let slugifiedLocationID = `${data.Description.Location}-${data.Description.RoomNumber}-${data.Description.Seat}`
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9-]/g, '-')
|
||||||
|
.replace(/-+/g, '-')
|
||||||
|
.replace(/^-|-$/g, '');
|
||||||
|
btn.setAttribute("data-location-id", slugifiedLocationID);
|
||||||
|
btn.setAttribute("data-location-name", data.Description.Location);
|
||||||
|
btn.setAttribute("data-room-number", data.Description.RoomNumber);
|
||||||
|
btn.setAttribute("data-seat", data.Description.Seat);
|
||||||
|
row.children[0].textContent = slugifiedLocationID;
|
||||||
|
row.children[1].textContent = data.Description.Location;
|
||||||
|
row.children[2].textContent = data.Description.RoomNumber;
|
||||||
|
row.children[3].textContent = data.Description.Seat;
|
||||||
|
|
||||||
|
// Close modal
|
||||||
|
bootstrap.Modal.getInstance(editModal).hide();
|
||||||
|
|
||||||
|
showToast('Location updated successfully', 'success');
|
||||||
|
} else {
|
||||||
|
showToast(`${result.reason || 'Update failed'}`, 'danger');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
showToast('Error contacting server', 'danger');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user