Enhance Phase 1 UI: Layout, Resizer, and Card adjustments
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 12s
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 12s
- Changed Phase 1 layout to 2/3 (Lager) and 1/3 (Table) split. - Added an interactive, draggable resizer handle between the two panes. - Made Lager cards ~10% wider and enforced a strict uniform height (200px). - Added manufacturer name to cards and applied text-overflow: ellipsis to prevent line breaks. - Reduced font sizes for metadata to fit compactly. - Safely removed SortableJS destroy() logic to prevent JS crash.
This commit is contained in:
@@ -38,8 +38,8 @@ if ($is_owner || $is_in_same_household) { $can_edit = true; }
|
||||
if (!$can_edit) { die("Zugriff verweigert."); }
|
||||
|
||||
$phase = isset($_GET['phase']) ? intval($_GET['phase']) : 0;
|
||||
$col_class_lager = ($phase == 1) ? 'col-lg-6' : (($phase == 2) ? 'd-none' : 'col-lg-4');
|
||||
$col_class_table = ($phase == 1 || $phase == 2) ? 'col-lg-6' : 'col-lg-4';
|
||||
$col_class_lager = ($phase == 1) ? 'col-phase1-lager' : (($phase == 2) ? 'd-none' : 'col-lg-4');
|
||||
$col_class_table = ($phase == 1) ? 'col-phase1-table' : (($phase == 2) ? 'col-lg-6' : 'col-lg-4');
|
||||
$col_class_rucksack = ($phase == 2) ? 'col-lg-6' : (($phase == 1) ? 'd-none' : 'col-lg-4');
|
||||
|
||||
$phase_title_suffix = ($phase == 1) ? " - Auswahl (Lager)" : (($phase == 2) ? " - Packen (Rucksack)" : "");
|
||||
@@ -151,41 +151,65 @@ $conn->close();
|
||||
/* Lager Grid */
|
||||
.lager-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(145px, 1fr));
|
||||
gap: 12px; padding: 5px;
|
||||
align-items: start; /* Prevents cards from stretching vertically */
|
||||
align-items: start;
|
||||
}
|
||||
.lager-card {
|
||||
border: 1px solid #eee; border-radius: 8px; padding: 6px;
|
||||
text-align: center; background: #fff; display: flex; flex-direction: column;
|
||||
transition: transform 0.1s, box-shadow 0.1s;
|
||||
height: 200px;
|
||||
}
|
||||
.lager-card:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.05); }
|
||||
.lager-img-wrapper {
|
||||
width: 100%; height: 120px; margin-bottom: 6px; display: flex;
|
||||
width: 100%; height: 90px; margin-bottom: 6px; display: flex;
|
||||
align-items: center; justify-content: center; overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.lager-img-wrapper img.lager-card-img {
|
||||
width: 100% !important; height: 100% !important;
|
||||
max-width: 100% !important; max-height: 120px !important;
|
||||
max-width: 100% !important; max-height: 90px !important;
|
||||
object-fit: contain !important; border-radius: 4px;
|
||||
}
|
||||
.lager-title {
|
||||
font-size: 0.85em; font-weight: 600; margin-bottom: 4px;
|
||||
line-height: 1.1; word-wrap: break-word;
|
||||
font-size: 0.85em; font-weight: 600; margin-bottom: 2px;
|
||||
line-height: 1.1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.lager-meta {
|
||||
font-size: 0.7em; color: #6c757d; margin-bottom: 4px;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
line-height: 1.1; flex-shrink: 0;
|
||||
}
|
||||
.lager-controls {
|
||||
display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 4px;
|
||||
display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: auto;
|
||||
}
|
||||
.table-status-text {
|
||||
font-size: 0.75em; color: #2e7d32; font-weight: 600;
|
||||
min-height: 14px; margin-top: 2px; visibility: hidden; line-height: 1;
|
||||
min-height: 12px; margin-top: 2px; visibility: hidden; line-height: 1;
|
||||
}
|
||||
.table-status-text.visible { visibility: visible; }
|
||||
|
||||
.editor-pane { display: flex; flex-direction: column; height: 100%; }
|
||||
.pane-content { flex-grow: 1; overflow-y: auto; padding: 10px; }
|
||||
|
||||
/* Layout Phase 1 Split */
|
||||
.col-phase1-lager { width: calc(66.666% - 5px); flex: 0 0 auto; }
|
||||
.col-phase1-table { width: calc(33.333% - 5px); flex: 0 0 auto; }
|
||||
.resizer {
|
||||
width: 10px;
|
||||
cursor: col-resize;
|
||||
background-color: transparent;
|
||||
transition: background-color 0.2s;
|
||||
border-radius: 4px;
|
||||
z-index: 10;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.resizer:hover, .resizer.resizing {
|
||||
background-color: rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
/* Remove empty dropzone on the table specifically */
|
||||
#table-container > .packed-item-container > .nested-sortable:empty {
|
||||
min-height: 0;
|
||||
@@ -218,9 +242,9 @@ $conn->close();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3" style="height: 75vh; min-height: 600px;">
|
||||
<div class="row g-2 flex-nowrap" style="height: 75vh; min-height: 600px; overflow-x: auto;" id="main-panes-container">
|
||||
<!-- LAGER -->
|
||||
<div class="<?php echo $col_class_lager; ?> h-100">
|
||||
<div class="<?php echo $col_class_lager; ?> h-100" id="pane-lager">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-light">
|
||||
<h5 class="mb-2"><i class="fas fa-boxes me-2"></i>Lagerbestand</h5>
|
||||
@@ -236,8 +260,13 @@ $conn->close();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RESIZER -->
|
||||
<?php if ($phase == 1): ?>
|
||||
<div class="resizer" id="resizer-1"></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- TISCH -->
|
||||
<div class="<?php echo $col_class_table; ?> h-100">
|
||||
<div class="<?php echo $col_class_table; ?> h-100" id="pane-table">
|
||||
<div class="card h-100 border-info">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-table me-2"></i>Auf dem Tisch</h5>
|
||||
@@ -249,7 +278,7 @@ $conn->close();
|
||||
</div>
|
||||
|
||||
<!-- RUCKSACK -->
|
||||
<div class="<?php echo $col_class_rucksack; ?> h-100">
|
||||
<div class="<?php echo $col_class_rucksack; ?> h-100" id="pane-rucksack">
|
||||
<div class="card h-100 border-success">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-backpack me-2"></i>Rucksäcke</h5>
|
||||
@@ -331,6 +360,37 @@ $conn->close();
|
||||
document.getElementById('table-container').addEventListener('change', handleQuantityChange);
|
||||
document.getElementById('carriers-container').addEventListener('change', handleQuantityChange);
|
||||
|
||||
const resizer = document.getElementById('resizer-1');
|
||||
const leftPane = document.getElementById('pane-lager');
|
||||
const rightPane = document.getElementById('pane-table');
|
||||
if (resizer && leftPane && rightPane) {
|
||||
let isResizing = false;
|
||||
resizer.addEventListener('mousedown', (e) => {
|
||||
isResizing = true;
|
||||
document.body.style.cursor = 'col-resize';
|
||||
document.body.style.userSelect = 'none';
|
||||
resizer.classList.add('resizing');
|
||||
});
|
||||
document.addEventListener('mousemove', (e) => {
|
||||
if (!isResizing) return;
|
||||
const container = document.getElementById('main-panes-container');
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const totalWidth = containerRect.width;
|
||||
const leftWidth = e.clientX - containerRect.left;
|
||||
const rightWidth = totalWidth - leftWidth - 10;
|
||||
leftPane.style.width = `calc(${(leftWidth / totalWidth) * 100}%)`;
|
||||
rightPane.style.width = `calc(${(rightWidth / totalWidth) * 100}%)`;
|
||||
});
|
||||
document.addEventListener('mouseup', () => {
|
||||
if(isResizing) {
|
||||
isResizing = false;
|
||||
document.body.style.cursor = 'default';
|
||||
document.body.style.userSelect = 'auto';
|
||||
resizer.classList.remove('resizing');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fullRender();
|
||||
});
|
||||
|
||||
@@ -393,14 +453,15 @@ $conn->close();
|
||||
const imgUrl = article.image_url ? article.image_url : 'assets/images/keinbild.png';
|
||||
const plusBtnClass = qtyTable > 0 ? 'btn-success' : 'btn-outline-primary';
|
||||
|
||||
const metaText = [article.manufacturer_name, article.product_designation].filter(Boolean).join(' - ');
|
||||
const cardHtml = `
|
||||
<div class="lager-card">
|
||||
<div class="lager-card" title="${article.name}${metaText ? ' (' + metaText + ')' : ''}">
|
||||
<div class="lager-img-wrapper">
|
||||
<img src="${imgUrl}" class="lager-card-img">
|
||||
</div>
|
||||
<div class="lager-title">${article.name}</div>
|
||||
${article.product_designation ? `<div class="small text-muted mb-1" style="line-height: 1.1;">${article.product_designation}</div>` : ''}
|
||||
<small class="text-muted d-block mb-1">${article.weight_grams}g</small>
|
||||
<div class="lager-meta">${metaText}</div>
|
||||
<small class="text-muted d-block mb-1" style="font-size:0.75em;">${article.weight_grams}g</small>
|
||||
<div class="lager-controls">
|
||||
<button class="btn btn-sm btn-outline-secondary" onclick="adjustTable(${aid}, -1)" ${disableMinus ? 'disabled' : ''}><i class="fas fa-minus"></i></button>
|
||||
<button class="btn btn-sm ${plusBtnClass}" onclick="triggerAddTable(${aid})" ${disablePlus ? 'disabled' : ''}><i class="fas fa-plus"></i></button>
|
||||
|
||||
Reference in New Issue
Block a user