mirror of
https://github.com/LD-Reborn/Berufsschule_HAM.git
synced 2025-12-20 06:51:55 +00:00
Implemented frontent Locations create button, fixed localization for frontend Locations
This commit is contained in:
@@ -26,8 +26,8 @@ public class LocationsController : Controller
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("Create")]
|
[HttpPost("Create")]
|
||||||
public async Task<bool> Create(LocationsCreateRequestModel model)
|
public async Task<bool> Create([FromBody]LocationsCreateRequestModel model)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace Berufsschule_HAM.Models;
|
|||||||
|
|
||||||
public class LocationsCreateRequestModel
|
public class LocationsCreateRequestModel
|
||||||
{
|
{
|
||||||
|
[JsonPropertyName("Description")]
|
||||||
public required LocationsDescription LocationsDescription { get; set; }
|
public required LocationsDescription LocationsDescription { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,4 +19,46 @@
|
|||||||
<data name="Create location" xml:space="preserve">
|
<data name="Create location" xml:space="preserve">
|
||||||
<value>Ort anlegen</value>
|
<value>Ort anlegen</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Location ID" xml:space="preserve">
|
||||||
|
<value>Ort ID</value>
|
||||||
|
</data>
|
||||||
|
<data name="Location name" xml:space="preserve">
|
||||||
|
<value>Ort Name</value>
|
||||||
|
</data>
|
||||||
|
<data name="Room number" xml:space="preserve">
|
||||||
|
<value>Raumnummer</value>
|
||||||
|
</data>
|
||||||
|
<data name="Seat" xml:space="preserve">
|
||||||
|
<value>Sitz</value>
|
||||||
|
</data>
|
||||||
|
<data name="Action" xml:space="preserve">
|
||||||
|
<value>Aktion</value>
|
||||||
|
</data>
|
||||||
|
<data name="Edit" xml:space="preserve">
|
||||||
|
<value>Anpassen</value>
|
||||||
|
</data>
|
||||||
|
<data name="Delete" xml:space="preserve">
|
||||||
|
<value>Löschen</value>
|
||||||
|
</data>
|
||||||
|
<data name="Location deleted successfully" xml:space="preserve">
|
||||||
|
<value>Ort erfolgreich gelöscht</value>
|
||||||
|
</data>
|
||||||
|
<data name="Unknown error" xml:space="preserve">
|
||||||
|
<value>Unbekannter Fehler</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error contacting server" xml:space="preserve">
|
||||||
|
<value>Server konnte nicht erreicht werden</value>
|
||||||
|
</data>
|
||||||
|
<data name="Location updated successfully" xml:space="preserve">
|
||||||
|
<value>Ort wurde erfolgreich angepasst</value>
|
||||||
|
</data>
|
||||||
|
<data name="Location update failed" xml:space="preserve">
|
||||||
|
<value>Ort konnte nicht angepasst werden</value>
|
||||||
|
</data>
|
||||||
|
<data name="Location created successfully" xml:space="preserve">
|
||||||
|
<value>Ort wurde erfolgreich erstellt</value>
|
||||||
|
</data>
|
||||||
|
<data name="Location creation failed" xml:space="preserve">
|
||||||
|
<value>Erstellung des Ortes ist fehlgeschlagen</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="mb-4 d-flex flex-wrap gap-2">
|
<div class="mb-4 d-flex flex-wrap gap-2">
|
||||||
<button class="btn btn-primary">@T["Create location"]</button>
|
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#createModal">@T["Create location"]</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -20,11 +20,11 @@
|
|||||||
<table class="table table-striped align-middle">
|
<table class="table table-striped align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>User</th>
|
<th>@T["Location ID"]</th>
|
||||||
<th>Asset ID</th>
|
<th>@T["Location name"]</th>
|
||||||
<th>Asset Name</th>
|
<th>@T["Room number"]</th>
|
||||||
<th>Location</th>
|
<th>@T["Seat"]</th>
|
||||||
<th>Action</th>
|
<th>@T["Action"]</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -45,13 +45,13 @@
|
|||||||
data-seat="@locationTableViewModel.Seat"
|
data-seat="@locationTableViewModel.Seat"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#editModal">
|
data-bs-target="#editModal">
|
||||||
Edit
|
@T["Edit"]
|
||||||
</button>
|
</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
|
@T["Delete"]
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@@ -161,41 +161,15 @@
|
|||||||
row.classList.add('table-danger');
|
row.classList.add('table-danger');
|
||||||
setTimeout(() => row.remove(), 300);
|
setTimeout(() => row.remove(), 300);
|
||||||
|
|
||||||
showToast('Location deleted successfully', 'success');
|
showToast('@T["Location deleted successfully"]', 'success');
|
||||||
} else {
|
} else {
|
||||||
showToast(`❌ ${result.reason}: ${result.exception || 'Unknown error'}`, 'danger');
|
showToast(`${result.reason}: ${result.exception || '@T["Unknown error"]'}`, 'danger');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
showToast('Error contacting server', 'danger');
|
showToast('@T["Error contacting server"]', 'danger');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -299,13 +273,130 @@
|
|||||||
// Close modal
|
// Close modal
|
||||||
bootstrap.Modal.getInstance(editModal).hide();
|
bootstrap.Modal.getInstance(editModal).hide();
|
||||||
|
|
||||||
showToast('Location updated successfully', 'success');
|
showToast('@T["Location updated successfully"]', 'success');
|
||||||
} else {
|
} else {
|
||||||
showToast(`${result.reason || 'Update failed'}`, 'danger');
|
showToast(`${result.reason || '@T["Location update failed"]'}`, 'danger');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
showToast('Error contacting server', 'danger');
|
showToast('@T["Error contacting server"]', 'danger');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Location Create Modal -->
|
||||||
|
<div class="modal fade" id="createModal" tabindex="-1" aria-labelledby="createModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header bg-primary text-white">
|
||||||
|
<h5 class="modal-title" id="createModalLabel">Create Location</h5>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form id="createForm">
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="createLocationName" class="form-label">Location Name</label>
|
||||||
|
<input type="text" class="form-control" id="createLocationName" name="LocationName" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="createRoomNumber" class="form-label">Room Number</label>
|
||||||
|
<input type="text" class="form-control" id="createRoomNumber" name="RoomNumber">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="createSeat" class="form-label">Seat</label>
|
||||||
|
<input type="text" class="form-control" id="createSeat" 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-primary">Create</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// --- CREATE MODAL ---
|
||||||
|
const createForm = document.getElementById('createForm');
|
||||||
|
|
||||||
|
createForm.addEventListener('submit', async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
Description: {
|
||||||
|
Location: createForm.createLocationName.value,
|
||||||
|
RoomNumber: createForm.createRoomNumber.value,
|
||||||
|
Seat: createForm.createSeat.value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/Locations/Create', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
const newLoc = data.Description;
|
||||||
|
const slugifiedLocationID = `${newLoc.Location}-${newLoc.RoomNumber}-${newLoc.Seat}`
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9-]/g, '-')
|
||||||
|
.replace(/-+/g, '-')
|
||||||
|
.replace(/^-|-$/g, '');
|
||||||
|
|
||||||
|
// Insert new row into the table dynamically
|
||||||
|
const tbody = document.querySelector('table tbody');
|
||||||
|
const newRow = document.createElement('tr');
|
||||||
|
newRow.innerHTML = `
|
||||||
|
<td>${slugifiedLocationID}</td>
|
||||||
|
<td>${newLoc.Location}</td>
|
||||||
|
<td>${newLoc.RoomNumber}</td>
|
||||||
|
<td>${newLoc.Seat}</td>
|
||||||
|
<td>
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<button class="btn btn-sm btn-warning btn-edit"
|
||||||
|
data-location-id="${slugifiedLocationID}"
|
||||||
|
data-location-name="${newLoc.Location}"
|
||||||
|
data-room-number="${newLoc.RoomNumber}"
|
||||||
|
data-seat="${newLoc.Seat}"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#editModal">
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-danger btn-delete"
|
||||||
|
data-location-id="${slugifiedLocationID}"
|
||||||
|
data-location-name="${newLoc.Location}"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#deleteModal">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
tbody.appendChild(newRow);
|
||||||
|
|
||||||
|
// Close modal
|
||||||
|
bootstrap.Modal.getInstance(document.getElementById('createModal')).hide();
|
||||||
|
createForm.reset();
|
||||||
|
showToast('@T["Location created successfully"]', 'success');
|
||||||
|
} else {
|
||||||
|
showToast(`${result.reason || '@T["Location creation failed"]'}`, 'danger');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
showToast('@T["Error contacting server"]', 'danger');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user